多线程:tkinter mainloop 不在主线程中

Multithreading: tkinter mainloop not in main thread

我想知道是否有办法 运行 在单独的线程(不是主线程)上运行 tkinter 主循环,以便终端“免费”。

假设我们有一个简单的 GUI:

import tkinter as tk       

class Application(tk.Frame):              
    def __init__(self, master=None):
        tk.Frame.__init__(self, master)   
        self.grid()                       
        self.createWidgets()

    def printHello(self):
        print("Hello")

    def createWidgets(self):
        self.quitButton = tk.Button(self, text='Quit',
            command=self.quit)            
        self.quitButton.grid(row=1,column=0)    
        self.printButton = tk.Button(self, text='Print',command=lambda: self.printHello())         
        self.printButton.grid(row=1,column=1) 
app = Application()                        
app.master.title('Sample application')     
app.mainloop()

观察到的行为:如果我运行这个文件使用PyCharm中的终端(比方说)使用:python application.py,终端然后被 tkinter 主循环“冻结”/“占用”,我无法在终端中输入任何内容。

期望的行为:如果我 运行 带有 python application.py 的 gui 文件,终端是“免费的”,因此它能够接受额外的命令。

我知道 python application.py & 应该可以释放终端,但这对我不起作用。我对线程或 GUI 进程不是很有经验,但是有没有办法 运行 不同进程/线程中的 tkinter 主循环,以便终端“免费”?

在主线程中使用终端时,您可以在后台线程中使用线程模块 运行 GUI。

试试这个代码。它将启动 GUI,然后允许从终端输入。

import tkinter as tk       
import threading

class Application(tk.Frame):              
    def __init__(self, master=None):
        tk.Frame.__init__(self, master)   
        self.grid()                       
        self.createWidgets()

    def printHello(self):
        print("Hello")

    def createWidgets(self):
        self.quitButton = tk.Button(self, text='Quit',
            command=self.quit) # exits background (gui) thread
        self.quitButton.grid(row=1,column=0)    
        self.printButton = tk.Button(self, text='Print',command=lambda: self.printHello())         
        self.printButton.grid(row=1,column=1) 

def runtk():  # runs in background thread
    app = Application()                        
    app.master.title('Sample application')     
    app.mainloop()
    
thd = threading.Thread(target=runtk)   # gui thread
thd.daemon = True  # background thread will exit if main thread exits
thd.start()  # start tk loop

while True:  # run in main thread
   x = input("Enter a value or Q to quit: ")
   if x.lower() == 'q':
      exit()
   print('You entered', x)