l7ll7
l7ll7

Reputation: 1329

Simple tkinter file path reader is not working

I'm new to tkinter and I want to read in a file. This simple operation turns out to be non-trivial. Here is my code:

import tkinter as tk 

from matplotlib.backends.backend_tkagg \
    import FigureCanvasTkAgg  ### PROBLEM 1: REMOVING THIS IMPORT CAUSES AN  
                              ### ERROR WHEN OPENING THE DIALOG


def op():
    global filename
    filename = tk.filedialog.askopenfilename()


root = tk.Tk()
mainframe = tk.Frame(root)
mainframe.grid(column=0, row=0)
mainframe.columnconfigure(0, weight=1)
mainframe.rowconfigure(0, weight=1)
tk.Button(mainframe, text="Open file", command=op).grid(column=0, row=1)
#print(filename)     ### PROBLEM 2: UNCOMMENTING THIS CAUSES AN ERROR
                     ### UNLESS I ADD <filename = ""> ABOVE THE op
                     ### FUNCTION DEFINITION
root.mainloop()

Questions:

1) It seems very weird that importing a totally different package, matplotlib, actually has an influence over whether my program works or not. Without that import, clicking on the opening button causes an error. With it, it works fine.
Could this be a bug?

2) Why is filename not accessible outside the function body, even though I'm declaring it global? A minimal working example that has the same structure as my tkinter code is this - and this works:

def test():
    global testname
    testname = 23


def call_test():
    test()


call_test()
print(testname)

Oddly enough, I can get my tkinter code to not produce an error, if I insert a filename = "" at the top - but I still can't actually print out the filename, it's just that the error disappears.

3) Is there any other, more elegant way to access the path of the file I'm opening without using global variables? What is the best practice?

Upvotes: 0

Views: 557

Answers (1)

Nae
Nae

Reputation: 15355

1

I don't think it's fair to call "...a totally different package...", let alone calling backend_tkagg that. Internally the second import also imports filedialog. That's why you don't need it. You can replace the second import simply with:

import tkinter.filedialog

2

At the time which:

print(filename)

is executed filename simply does not exist as op was never called before. Python isn't compiled, it is interpreted, it simply skips runtime error(s) until the lines that cause it are run. Try:

op()
print(filename)

to see the difference.


3

Your file path reader does work. It's just you try to print the filepath before it starts to exist, or before it has a path in it.

I think another way in the context would be:

...
def op():
    global root
    root.filename = tk.filedialog.askopenfilename()
    print(root.filename)

Upvotes: 1

Related Questions