两个 tkinter GUI 变量之间的冲突

时间:2021-04-30 06:39:42

标签: python tkinter filedialog

我有一个主 GUI 和辅助 GUI,辅助 GUI 可以独立调用,也可以通过按主 GUI 上的按钮调用。

场景 1:当我直接打开辅助 GUI 时,一切正常。

场景 2:当我从主 GUI 调用辅助 GUI 时。两个 GUI 的变量之间存在一些冲突。我创建了一个高度简化的示例,它也产生了同样的问题。

问题:从主 GUI 打开辅助 GUI 后,当我们尝试从第二个 GUI 中选择路径时,它根本没有出现在入口小部件中。但是,它在变量中设置值并且可以打印。

我正在寻找一种解决方案来帮助我分别保留这两个文件(我不想在 MainGUI 中合并辅助 GUI)

我知道,这是我犯的一些愚蠢的错误,但任何帮助将不胜感激。

Main_GUI.py

import tkinter as tk
from tkinter import filedialog
import os
#from b import *

class App:
    def __init__(self, master):
        self.master = master
        master.geometry('470x100')
        master.title("Main GUI")

        # Path
        self.labelframe0 = tk.LabelFrame(master, text="Enter path",width=10,height=55, font=("TkDefaultFont", 9, "bold"))
        self.labelframe0.pack(fill="both", expand="yes")
        self.folder_path = tk.StringVar()
        self.lbl1 = tk.Entry(self.labelframe0, textvariable=self.folder_path, width=67)
        self.lbl1.place(x=0, y=4)
        self.button2 = tk.Button(self.labelframe0, text="Browse", bg="orange", fg="black", command=self.browse_button)
        self.button2.place(x=410, y=0)

        # Button
        self.labelframe1 = tk.LabelFrame(master, text="Button",width=10,height=50, font=("TkDefaultFont", 9, "bold"))
        self.labelframe1.pack(fill="both", expand="yes")
        self.btn2 = tk.Button(self.labelframe1, text="Secondary GUI", bg="orange", fg="black", command=self.SecondaryGUI)
        self.btn2.place(x=0, y=0)


    def SecondaryGUI(self): 
        with open(os.path.join(os.path.dirname(os.path.abspath(__file__)), "b.py"), "r") as source_file:
            code = compile(source_file.read(), os.path.join(os.path.dirname(os.path.abspath(__file__)), "b.py"), "exec")
        exec(code, {})
        #b()

    def browse_button(self):
        self.folder_path.__del__
        filename = filedialog.askdirectory()
        self.folder_path.set(filename)
        print(self.folder_path.get())
        

def main():
    window = tk.Tk()
    root = App(window)
    window.mainloop()

if __name__ == '__main__':
    main()

Secondary.py

import tkinter as tk
from tkinter import filedialog
import os

class a_app:
    def __init__(self, window):
        self.window = window
        self.window.geometry('400x60')
        self.window.title("Secondary GUI")

        # path
        self.labelframe0 = tk.LabelFrame(self.window, text="Path to save",width=10,height=55, font=("TkDefaultFont", 9, "bold"))
        self.labelframe0.pack(fill="both", expand="yes")
        self.folder_path = tk.StringVar()
        self.lbl1 = tk.Entry(self.labelframe0, textvariable=self.folder_path, width=53)
        self.lbl1.place(x=0, y=4)
        self.button2 = tk.Button(self.labelframe0, text="Browse", bg="orange", fg="black", command=self.browse_button)
        self.button2.place(x=325, y=0)

    def browse_button(self):
        self.folder_path.__del__
        self.filename = filedialog.askdirectory(parent=self.window)
        self.folder_path.set(self.filename)
        print(self.folder_path.get())

inst = tk.Tk()
root = a_app(inst)
inst.mainloop()

曼尼什

1 个答案:

答案 0 :(得分:1)

每次创建 Tk() 的新实例时,都会创建一个新的 Tcl 解释器。每个解释器就像一个独立的沙箱,拥有自己的内存。因此,其他解释器无法访问在一个 Tcl 解释器中创建的小部件和变量。

当您使用 tk.StringVar() 而不传递 master 关键字参数时,tkinter 必须猜测要使用哪个解释器。它总是选择创建的 Tk() 的第一个实例。这就是您遇到问题的原因。

这就是为什么人们通常建议只使用一次 tk.Tk() 并在需要更多窗口时使用 tk.Toplevel()