多线程: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)
我想知道是否有办法 运行 在单独的线程(不是主线程)上运行 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)