Taral
Taral

Reputation: 11

Attribute error in opening file dialog in python GUI using tkinter

I am starting to learn Python and the tkinter package and I am writing a program to load a text file on the GUI window. To open the file browser, I installed the button and its necessary function as shown in the below code. The program runs but when I click on the "browse" button, I am getting an attribute error saying : "'assign_1' object has no attribute 'var_filename'". It would be great if anyone could help me with this.

from tkinter import *
from tkinter import messagebox
from tkinter import simpledialog
from tkinter import filedialog
from math import *
from numpy  import *
import string

root = Tk()

def close_window_callback(root):
   if messagebox.askokcancel("Quit", "Do you really wish to quit?"):
   root.destroy()


class assign_1:
    def __init__(self,master):
        self.master = master
        frame = Frame(master)
        frame.pack()
        self.canvas = Canvas(master,width=1000,height=1000, bg="yellow")


        self.button_browse = Button(frame, text="Browse",
command=self.browse_file)
        self.button_browse.pack()

        self.button_load = Button(frame, text="Load")
        self.button_load.pack(side = LEFT)

        self.canvas.pack(expand=YES, fill=BOTH)

def browse_file(self):
    self.var_filename.set(filedialog.askopenfilename(filetypes=[("allfiles","*"),("pythonfiles","*.txt")]))
    filename = self.var_filename.get()
    print(filename)

root.protocol("WM_DELETE_WINDOW", lambda root_window=root:  close_window_callback(root_window))
assign_1(root)

root.mainloop()

Upvotes: 0

Views: 1674

Answers (2)

fhdrsdg
fhdrsdg

Reputation: 10552

Although, as Rinzler pointed out, your indentation is wrong in the code you posted, that would lead to another error (AttributeError: assign_1 instance has no attribute 'browse_file'). So I'm guessing the indentation in the code you actually use is correct.

The problem is that you try to use self.var_filename.set(...) without having defined what self.var_filename is. If you want it to be a StringVar, which seems to be the case since you use set and get, you have to initialize it. To do this you should put self.var_filename = StringVar(master) in the class' __init__ function. A small example demonstrating this:

root = Tk()

class assign_1:
    def __init__(self, master):
        self.master = master
        self.var_filename = StringVar(master)

        self.button_browse = Button(master, text="Browse", command=self.browse_file)
        self.button_browse.pack()

    def browse_file(self):
        self.var_filename.set(filedialog.askopenfilename(filetypes=[("allfiles","*"),("pythonfiles","*.txt")]))
        filename = self.var_filename.get()
        print(filename)


assign_1(root)
root.mainloop()

However, from the looks of it, in your case there is no need to use a tkinter StringVar, just use a normal string variable:

root = Tk()

class assign_1:
    def __init__(self, master):
        self.master = master

        self.button_browse = Button(master, text="Browse", command=self.browse_file)
        self.button_browse.pack()

    def browse_file(self):
        self.filename = filedialog.askopenfilename(filetypes=[("allfiles","*"),("pythonfiles","*.txt")])
        print(self.filename)


assign_1(root)
root.mainloop()

Upvotes: 1

nbro
nbro

Reputation: 15847

The indentation is wrong. The function browse_file you wanted to define as method of the class assign_1 (use capitalise letters to declare name of classes) is a global function as you defined it.

You have also not defined self.var_filename anywhere, so it will then give you the error:

AttributeError: 'assign_1' object has no attribute 'var_filename'

Under the function close_window_callback, you have also wrong indentation.

Upvotes: 1

Related Questions