Reputation: 381
I have two button to store the path of opened file but I feel this process is duplicating code and uses global. I'm wondering if there is a way to do a return in the function and store that return value in a variable.
Here is my current code
browsebutton = Button(root, text="This Week's Report", command=getFilecurrent)
browsebutton.grid(row=0, column=0)
browsebutton2 = Button(root, text="Last Week's Report", command=getFilepast)
browsebutton2.grid(row=0, column=1)
def getFilecurrent():
global path
# open dialog box to select file
path = filedialog.askopenfilename(initialdir="/", title="Select file")
def getFilepast():
global pathpast
# open dialog box to select file
pathpast = filedialog.askopenfilename(initialdir="/", title="Select file")
Ideally I was thinking doing something like this
def getFilepath():
# open dialog box to select file
path = filedialog.askopenfilename(initialdir="/", title="Select file")
return path
and somehow store the return path to a variable. This way, I will only need one path storing function and will not have to use global variables.
Upvotes: 1
Views: 2085
Reputation: 365597
Usually, what you're trying to do is a good idea. But it won't work in this case. The code that's calling getFilepast
isn't something you write, it's code deep inside tkinter, and it has no idea what to do with a path that you return to it.
The usual way to deal with this is to create a class, and store values as an instance of the class, like this:
class PathyThing:
def __init__(self):
self.browsebutton2 = Button(root, text="Last Week's Report", command=self.getFilepast)
self.browsebutton2.grid(row=0, column=1)
# etc.
def getFilepast(self):
# open dialog box to select file
self.pathpast = filedialog.askopenfilename(initialdir="/", title="Select file")
# etc.
pathy = PathyThing()
Now, any other method of pathy
can see self.pathpast
.
Often, you want to make this class a subclass of something like tkinter.Frame
, and then create a PathyFrame
instead of a normal Frame
. There are examples of this in most tkinter tutorials.
I think you may have also wanted to create a single function that handles both buttons' callbacks. You can do that by using partial
to pass an extra argument to the function. But with your example, you're kind of stuck—the only real difference between the two functions is which variable they set, and there's no nice way to pass that information down. Usually, however, you want to actually do something, not just store a value in a variable. For example, let's say we wanted to read the first line from the report file and set the contents of a label to match it. Then we'd have something we can factor out:
from functools import partial
def getPath(label):
path = filedialog.askopenfilename(initialdir='/', title="Select file")
with open(path) as f:
firstline = next(f)
label.config(text=firstline)
label = Label(root)
label.grid(row=1, column=0)
browsebutton = Button(root, text="This Week's Report", command=partial(getFile, label))
browsebutton.grid(row=0, column=0)
label2 = Label(root)
label.grid(row=1, column=1)
browsebutton2 = Button(root, text="Last Week's Report", command=partial(getFile, label2))
browsebutton2.grid(row=0, column=1)
Upvotes: 1