Using Python, how do you call a tkinter GUI from a

2019-03-06 08:24发布

问题:

I created a couple of GUIs using tkinter. But now I am interested in combining them into one caller GUI. So the caller GUI would have buttons that, when clicked, would open the other GUIs. However, I cannot get it to work. I've done the imports correctly (I think), edited the main functions in the subGUIs, and added the command=GUI.main in my buttons. I get it to load but I get errors about missing files...but when I run a GUI by itself it works fine.

In my research, I read that there can only be one mainloop in a Tkinter program. Basically, I cannot use a Tkinter GUI to call another Tkinter GUI. Do you know what I can do different, for instance, can I create the caller GUI using wxPython and have it call all other GUIs that use Tkinter?

Thank you!

回答1:

You can't "call" another GUI. If this other GUI creates its own root window and calls mainloop(), your only reasonable option is to spawn a new process. That's a simple solution that requires little work. The two GUIs will be completely independent of each other.

If you have control over the code in both GUIs and you want them to work together, you can make the base class of your GUI a frame rather than a root window, and then you can create as many windows as you want with as many GUIs as you want.

For example, let's start with a simple GUI. Copy the following and put it in a file named 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()

You can run that GUI normally with something like python GUI1.py.

Now, make an exact copy of that file and name it GUI2.py. You can also run it in the same manner: python GUI2.py

If you want to make a single program that has both, you can create a third file that looks like this:

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()

Depending on your OS and window manager, one window might be right on top of the other, so you might need to move it to see both.



回答2:

Thank you for the ideas. At first, your code wouldn't print the text on the toplevel window. So I edited it a little and it worked! Thank you. GUI1 and GUI2 look like:

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()

And then the caller looks like this:

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()