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

python在后台运行任务,同时允许tkinter处于活动状态,python,tkinter,python-multithreading,Python,Tkinter,Python Multithreading,当我的程序执行python GUI时,会冻结。这是我的主要代码。我可以在穿线方面得到一些帮助吗?所以执行是在后台进行的,如果我想结束执行,我仍然可以使用GUI中的“x”按钮?目前我只是要求用户关闭cmd来结束程序 if __name__ == "__main__": root = Tk() root.title('Log') root.geometry("400x220") font1=('times', 15) font2=('times', 10

当我的程序执行python GUI时,会冻结。这是我的主要代码。我可以在穿线方面得到一些帮助吗?所以执行是在后台进行的,如果我想结束执行,我仍然可以使用GUI中的“x”按钮?目前我只是要求用户关闭cmd来结束程序

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:spawhthread(fcn)
,以便将函数对象设置为回调。答案已更新以反映这一点。很抱歉错过了


当您尝试运行其他功能时,GUI mainloop将冻结,并且无法重新启动自身(因为它已冻结)

假设您希望在GUI主循环旁边运行的命令是
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
queue=queue.queue()

按钮(root,text='START',command=lambda:spawnthread(myfunction)).pack()#在线程中应该做什么?您是否计划更新GUI?请注意,Tkinter不是线程安全的。
main
函数在哪里?问题代码在哪里?也许您可以使用
tk.After()
?我一直在spawhthread periodiccall(线程)文件X的第30行中的periodiccall After(100,lambda:periodiccall(线程))name错误:未定义全局名称'After'。请尝试改用root.after(…)命令。@user2980048甚至root.after(…)。我已经有一段时间没有使用tkinter了,我不确定哪一个是最好的。谢谢,在使用root.after(..)之后,它现在起作用了。但是,为什么我的main()函数在没有单击开始按钮的情况下执行?它以前是否在没有单击开始按钮的情况下运行?