pythonpython-3.xtkinterglobal-variablesfiledialog

filedialog, tkinter and opening files


I'm working for the first time on coding a Browse button for a program in Python3. I've been searching the internet and this site, and even python standard library.

I have found sample code and very superficial explanations of things, but I haven't been able to find anything that addresses the problem I'm having directly, or a good enough explanation so I can customize code to my needs.

Here is the relevant snippet:

Button(self, text = "Browse", command = self.load_file, width = 10)\
        .grid(row = 1, column = 0, sticky = W) .....


 def load_file(self):

    filename = filedialog.askopenfilename(filetypes = (("Template files", "*.tplate")
                                                         ,("HTML files", "*.html;*.htm")
                                                         ,("All files", "*.*") ))
    if filename: 
        try: 
            self.settings["template"].set(filename)
        except: 
            messagebox.showerror("Open Source File", "Failed to read file \n'%s'"%filename)
            return

The method is a hybrid of some code I found along the way with my own customizations. It seems like I finally got it to work (kinda), though its not exactly how I need it.

I get this error when I activate the 'Browse' button: NameError: global name 'filedialog' is not defined.

I've found fairly similar issues along the way but all the solutions suggested I have covered. I went into the 'filedialog' help section of IDLE but didn't glean anything from there either.

Would someone mind providing a break down and a little guidance on this; none of my books address it specifically, and I've checked all the solutions provided to others—I'm lost.


Solution

  • The exception you get is telling you filedialog is not in your namespace. filedialog (and btw messagebox) is a tkinter module, so it is not imported just with from tkinter import *

    >>> from tkinter import *
    >>> filedialog
    Traceback (most recent call last):
      File "<interactive input>", line 1, in <module>
    NameError: name 'filedialog' is not defined
    >>> 
    

    you should use for example:

    >>> from tkinter import filedialog
    >>> filedialog
    <module 'tkinter.filedialog' from 'C:\Python32\lib\tkinter\filedialog.py'>
    >>>
    

    or

    >>> import tkinter.filedialog as fdialog
    

    or

    >>> from tkinter.filedialog import askopenfilename
    

    So this would do for your browse button:

    from tkinter import *
    from tkinter.filedialog import askopenfilename
    from tkinter.messagebox import showerror
    
    class MyFrame(Frame):
        def __init__(self):
            Frame.__init__(self)
            self.master.title("Example")
            self.master.rowconfigure(5, weight=1)
            self.master.columnconfigure(5, weight=1)
            self.grid(sticky=W+E+N+S)
    
            self.button = Button(self, text="Browse", command=self.load_file, width=10)
            self.button.grid(row=1, column=0, sticky=W)
    
        def load_file(self):
            fname = askopenfilename(filetypes=(("Template files", "*.tplate"),
                                               ("HTML files", "*.html;*.htm"),
                                               ("All files", "*.*") ))
            if fname:
                try:
                    print("""here it comes: self.settings["template"].set(fname)""")
                except:                     # <- naked except is a bad idea
                    showerror("Open Source File", "Failed to read file\n'%s'" % fname)
                return
    
    
    if __name__ == "__main__":
        MyFrame().mainloop()
    

    enter image description here