Python,Tkinter:如何使用线程防止 tkinter gui 主循环崩溃

2024-04-30

嗨,我有一个小的 python gui 界面,有两个按钮,开始(启动计数器)和停止(假设停止计数器),计数器是一个无限循环,因为我不希望它结束​​,除非第二个按钮是点击。问题是当第一个按钮的功能仍在运行时无法单击第二个按钮。 我读到我需要使用线程并且我已经尝试过,但我不完全理解如何做到这一点。请帮忙。

from Tkinter import *
import threading


class Threader(threading.Thread):
    def run(self):
        for _ in range(10):
            print threading.current_thread().getName()

    def main(self):
        import itertools
        for i in itertools.count(1, 1):
            print i

    def other(self):
        print "Other"

m = Threader(name="main")
o = Threader(name="other")

try:
    '''From here on we are building the Gui'''
    root = Tk()

    '''Lets build the GUI'''
    '''We need two frames to help sort shit, a left and a right vertical frame'''
    leftFrame = Frame(root)
    leftFrame.pack(side=LEFT)
    rightFrame = Frame(root)
    rightFrame.pack(side=RIGHT)
    '''Widgets'''
    '''Buttons'''
    playButton = Button(leftFrame, text="Play", fg="blue", command=m.main)
    stopButton = Button(rightFrame, text="Stop", fg="red", command=o.other)
    playButton.pack(side=TOP)
    stopButton.pack(side=BOTTOM)

    root.mainloop()
except Exception, e:
    print e

这是一个使用的简短示例threading。我拿出你的other功能,我不知道你为什么使用itertools这里。我也将其取出并使用简单的线程示例进行简单设置。

一些东西:

您设置使用threading.Thread作为基类Threader,但你实际上从未已初始化基类。

每当你使用线程时,你通常想要定义一个run方法然后使用start()启动线程。呼唤start()将会通知run.

您需要使用线程来防止 GUI 阻塞,因为 tkinter 只是一个巨大循环上的一个线程。因此,每当您有一些长时间运行的进程时,它就会阻塞该线程,直到当前进程完成。这就是为什么它被放在另一个线程中。 Python 有一个东西叫做GIL https://wiki.python.org/moin/GlobalInterpreterLock,这可以防止true并行化(我编了这个词),因为一次只能使用一个线程。相反,它使用时间切片,GIL 在它们之间进行“轮询”以给出外貌多个任务同时运行。对于真正的并行处理,您应该使用multiprocessing.

在下面的代码中我使用了self.daemon = True。将线程设置为守护进程会在退出主程序时杀死它(在本例中为 Tk GUI)

from tkinter import *
import threading, time

class Threader(threading.Thread):

    def __init__(self, *args, **kwargs):

        threading.Thread.__init__(self, *args, **kwargs)
        self.daemon = True
        self.start()

    def run(self):

         while True:
            print("Look a while true loop that doesn't block the GUI!")
            print("Current Thread: %s" % self.name)
            time.sleep(1)

if __name__ == '__main__':

    root = Tk()
    leftFrame = Frame(root)
    leftFrame.pack(side=LEFT)
    rightFrame = Frame(root)
    rightFrame.pack(side=RIGHT)
    playButton = Button(leftFrame, text="Play", fg="blue", 
        command= lambda: Threader(name='Play-Thread'))
    stopButton = Button(rightFrame, text="Stop", fg="red", 
        command= lambda: Threader(name='Stop-Thread'))
    playButton.pack(side=TOP)
    stopButton.pack(side=BOTTOM)
    root.mainloop()
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Python,Tkinter:如何使用线程防止 tkinter gui 主循环崩溃 的相关文章

随机推荐