【问题标题】:Multithreading: tkinter mainloop not in main thread多线程:tkinter mainloop 不在主线程中
【发布时间】:2021-01-27 09:31:10
【问题描述】:

我想知道是否有办法在单独的线程(不是主线程)上运行 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 主循环,以便终端“免费”?

【问题讨论】:

  • 尝试使用pythonwpythonw application.py
  • 但是有没有办法手动实现线程?

标签: python multithreading tkinter thread-safety python-multithreading


【解决方案1】:

您可以使用线程模块在后台线程中运行 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)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-08-26
    • 1970-01-01
    • 2018-06-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-12-21
    相关资源
    最近更新 更多