【问题标题】:Using Python, how do you call a tkinter GUI from another GUI?使用 Python,如何从另一个 GUI 调用 tkinter GUI?
【发布时间】:2018-02-15 23:08:49
【问题描述】:

我使用 tkinter 创建了几个 GUI。但现在我有兴趣将它们组合成一个调用者 GUI。所以调用者的 GUI 会有一些按钮,当点击这些按钮时,会打开其他的 GUI。但是,我无法让它工作。我已经正确地完成了导入(我认为),编辑了 subGUI 中的主要功能,并在我的按钮中添加了 command=GUI.main。我让它加载,但我收到有关丢失文件的错误......但是当我自己运行 GUI 时它工作正常。

在我的研究中,我读到 Tkinter 程序中只能有一个主循环。基本上,我不能使用 Tkinter GUI 来调用另一个 Tkinter GUI。你知道我可以做些什么不同的事情吗,例如,我可以使用 wxPython 创建调用者 GUI 并让它调用所有其他使用 Tkinter 的 GUI?

谢谢!

【问题讨论】:

  • 我不能 100% 确定,但我认为一次只能运行一个 Tk().mainloop。但是不需要多个单独的 GUI。 Just create different "pages".
  • 感谢您的回复。这是个好主意。但是,这似乎比仅仅调用 GUI 运行要多得多。假设我将子 GUI 构建到 .exe(使用 pyinstaller)中,然后像从调用者 GUI 中的应用程序一样运行它们。知道这是否可行吗?

标签: python user-interface tkinter wxpython


【解决方案1】:

您不能“调用”另一个 GUI。如果这个其他 GUI 创建自己的根窗口并调用mainloop(),那么您唯一合理的选择是生成一个新进程。这是一个简单的解决方案,只需要很少的工作。这两个 GUI 将完全相互独立。

如果您可以控制两个 GUI 中的代码并且希望它们一起工作,则可以将 GUI 的基类设置为框架而不是根窗口,然后您可以创建任意数量的窗口尽可能多的 GUI。

例如,让我们从一个简单的 GUI 开始。复制以下内容并将其放入名为 GUI1.py 的文件中:

import tkinter as tk

class GUI(tk.Frame):
    def __init__(self, window):
        tk.Frame.__init__(self)
        label = tk.Label(self, text="Hello from %s" % __file__)
        label.pack(padx=20, pady=20)

if __name__ == "__main__":
    root = tk.Tk()
    gui = GUI(root)
    gui.pack(fill="both", expand=True)
    tk.mainloop()

您可以使用 python GUI1.py 之类的内容正常运行该 GUI。

现在,制作该文件的精确副本并将其命名为 GUI2.py。你也可以用同样的方式运行它:python GUI2.py

如果你想制作一个同时拥有这两者的程序,你可以创建第三个文件,如下所示:

import tkinter as tk
import GUI1
import GUI2

# the first gui owns the root window
win1 = tk.Tk()
gui1 = GUI1.GUI(win1)
gui1.pack(fill="both", expand=True)

# the second GUI is in a Toplevel
win2 = tk.Toplevel(win1)
gui2 = GUI2.GUI(win2)
gui2.pack(fill="both", expand=True)

tk.mainloop()

根据您的操作系统和窗口管理器,一个窗口可能位于另一个窗口的正上方,因此您可能需要移动它才能同时看到这两个窗口。

【讨论】:

    【解决方案2】:

    感谢您的想法。起初,您的代码不会在顶层窗口上打印文本。所以我对它进行了一点编辑,它奏效了!谢谢你。 GUI1 和 GUI2 看起来像:

    import tkinter as tk
    
    def GUI1(Frame):
        label = tk.Label(Frame, text="Hello from %s" % __file__)
        label.pack(padx=20, pady=20)
        return
    
    if __name__ == "__main__":
        root = tk.Tk()
        GUI1(root)
        root.mainloop()
    

    然后调用者是这样的:

    from tkinter import *
    import GUI1
    import GUI2
    
    def call_GUI1():
        win1 = Toplevel(root)
        GUI1.GUI1(win1)
        return
    
    def call_GUI2():
        win2 = Toplevel(root)
        GUI2.GUI2(win2)
        return
    
    # the first gui owns the root window
    if __name__ == "__main__":
        root = Tk()
        root.title('Caller GUI')
        root.minsize(720, 600)
        button_1 = Button(root, text='Call GUI1', width='20', height='20', command=call_GUI1)
        button_1.pack()
        button_2 = Button(root, text='Call GUI2', width='20', height='20', command=call_GUI2)
        button_2.pack()
        root.mainloop()
    

    【讨论】:

      猜你喜欢
      • 2014-05-21
      • 1970-01-01
      • 1970-01-01
      • 2020-01-28
      • 1970-01-01
      • 2016-02-21
      • 2020-04-19
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多