在后台运行任务,同时允许tkinter处于活动状态

2022-04-17 00:00:00 python tkinter python-multithreading

问题描述

当我的程序执行时,python图形用户界面冻结。以下是我的主要代码。我可以在穿线方面得到一些帮助吗?所以执行是在后台进行的,如果我想结束执行,我仍然可以使用图形用户界面中的"x"按钮?当前我只要求用户关闭命令以结束程序。

if __name__ == "__main__":

    root = Tk() 
    root.title('Log')
    root.geometry("400x220") 
    font1=('times', 15)
    font2=('times', 10)
    #Label inside root 
    Label(root, relief=GROOVE, font=font2, text="level").pack() 
    variable = StringVar(root)
    variable.set("INFO") # default value

    w = OptionMenu(root, variable, "CRITICAL", "DEBUG")
    w.pack()
    Button(root, font=font1, background= "yellow", text='START',command=main).pack()
    Label(root, text="To end just close the CMD window").pack()

    root.mainloop()

解决方案

更新:原来按钮回调正在自动运行launch,因为没有将函数对象设置为回调,而是被调用的函数本身。修复方法是替换回调lambda: spawnthread(fcn),以便将函数对象设置为回调。答案已经更新,以反映这一点。很抱歉错过了。


当您尝试运行其他函数时,图形用户界面主循环将冻结,并且无法重新启动(因为它已冻结)。

假设您希望与图形用户界面主循环一起运行的命令是myfunction

导入:

import time
import threading
import Queue

您需要设置ThreadedClient类:

class ThreadedClient(threading.Thread):
    def __init__(self, queue, fcn):
        threading.Thread.__init__(self)
        self.queue = queue
        self.fcn = fcn
    def run(self)
        time.sleep(1)
        self.queue.put(self.fcn())

def spawnthread(fcn):
    thread = ThreadedClient(queue, fcn)
    thread.start()
    periodiccall(thread)

def periodiccall(thread):
    if(thread.is_alive()):
        root.After(100, lambda: periodiccall(thread))

然后希望调用该函数的小部件改为调用spawnthread函数:

queue = Queue.Queue()

Button(root, text='START',command=lambda: spawnthread(myfunction)).pack() #<---- HERE
注意:我是从我的多线程Tkinter图形用户界面改编的;我将所有的帧都包装在类中,所以它可能有一些错误,因为我必须对它进行一些调整。

相关文章