Home > Net >  Passing variable to external module from tkinter GUI
Passing variable to external module from tkinter GUI

Time:10-23

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)
  • Related