I am just writing a small GUI for data analysis purposes and I thought it would be a good idea to have one file for the GUI-stuff with tkinter and the functional stuff in another file. However, somehow I am not able to pass the correct value to the module where the functions are located. Simplified version of the problem: One file is the GUI.py:
import tkinter as tk
from tkinter import filedialog as fd
import readBinary as rb
import functools as ft
filename = "EXTERNAL"
def mytest():
global filename
filename = fd.askopenfilename(filetypes=(("Binary Data", "*.bin"),("All files", "*.*")))
print(filename)
def printtest():
global filename
print(filename)
def gui():
global filename
root = tk.Tk()
openB = tk.Button(master=root,text="File",command=mytest)
openB.pack()
printB = tk.Button(master=root,text="Print",command=printtest)
printB.pack()
#filename = "INTERNAL"
test = tk.Button(master=root,text="Test",command=ft.partial(rb.doIt,filename))
test.pack()
root.mainloop()
if __name__ == "__main__":
gui()
And the other file, in this case named readBinary.py:
def doIt(filename):
print(filename)
if __name__ == "__main__":
pass
The problem is now:
- using the printtest and the imported doIt-function it prints "EXTERNAL", which is clear.
- when the mytest() is called and a file is choosen, it prints the path of this file. Also when I call the printtest now it prints the path. but the imported doIt still prints "EXTERNAL"
- on the other hand, when I uncomment the filename = "INTERNAL" in the gui()-function both, the printtest and the imported doIt print "INTERNAL"
So the argument pass seems to work AND the filename from the choosen file is accessible from the gui()-function. So how is it possible that the combination gives the wrong result?
CodePudding user response:
Apart from the fact that your use of partial
is not how you intended to use, here is a small fix that will achieve your intended behavior.
Instead of passing the value of filename
when using partial
, you have to pass a reference of object from which you can access the updated value of filename
. Here, I am using a Class
object. You may wrap it in list
, dict
or other object as well.
import tkinter as tk
from tkinter import filedialog as fd
import readBinary as rb
import functools as ft
class FILE:
name = "EXTERNAL"
def mytest():
return_value = fd.askopenfilename(filetypes=(("Binary Data", "*.bin"), ("All files", "*.*")))
if return_value:
FILE.name = return_value
print(FILE.name)
def printtest():
print(FILE.name)
def gui():
root = tk.Tk()
openB = tk.Button(master=root, text="File", command=mytest)
openB.pack()
printB = tk.Button(master=root, text="Print", command=printtest)
printB.pack()
test = tk.Button(master=root, text="Test", command=ft.partial(rb.doIt, FILE))
test.pack()
root.mainloop()
if __name__ == "__main__":
gui()
readBinary.py
def doIt(class_obj):
print(class_obj.name)