1

我的问题与此类似:Python TKinter multiple operations。但是,提供的答案对我没有帮助,因为它指向了一篇包含可能使用的功能列表的文章。我想看看解决方案的实际实现。

我的问题:我的框架上有两个按钮。只要将切换变量设置为true,一个按钮就会调用“执行”功能。第二个按钮将切换值设置为 False。我希望“执行”功能在按下执行按钮后继续运行,但在按下第二个(切换为假)按钮时停止。但是,一旦我按“执行”,框架就会卡住。我理解它是因为回调。我怎样才能解决这个问题?这是我的示例代码:

from Tkinter import *
from time import sleep

class App:

    def __init__(self, master):

        self.toggle = False
        frame = Frame(master)
        frame.pack()

        self.exeButton = Button(frame, text="Execute", fg="blue", command=self.execute)
        self.exeButton.pack(side=LEFT)

        self.tOffButton = Button(frame, text="Toggle Off", command=self.toggleOff)
        self.tOffButton.pack(side=LEFT)

    def execute(self):
        self.toggle = True
        while(self.toggle):
            print "hi there, everyone!"
            sleep(2)

    def toggleOff(self):
    self.toggle = False

root = Tk()
app = App(root)
root.mainloop()
4

1 回答 1

4

简短的回答,你不能完全按照你的意愿去做。Tkinter 是单线程的——当你调用sleep(2)它时,它会完全按照你的要求去做:它会休眠。

如果您的目标是在布尔标志设置为 True 的情况下每 2 秒执行一次,您可以使用after来安排将来运行的作业。如果该作业还使用 after 来(重新)调度自身,那么您实际上创建了一个无限循环,其中实际的循环机制是事件循环本身。

我已经获取了您的代码并进行了一些细微的修改,以向您展示如何连续执行某些操作,直到一个标志告诉它停止。我冒昧地将“切换”重命名为“运行”以使其更容易理解。我也只使用一种方法来打开和关闭执行。

from Tkinter import *
from time import sleep

class App:

    def __init__(self, master):

        self.master = master
        self.running = False
        frame = Frame(master)
        frame.pack()

        self.exeButton = Button(frame, text="Execute", fg="blue", 
            command=lambda: self.execute(True))
        self.exeButton.pack(side=LEFT)

        self.tOffButton = Button(frame, text="Toggle Off", 
            command=lambda: self.execute(False))
        self.tOffButton.pack(side=LEFT)

    def execute(self, running=None):
        if running is not None:
            self.running = running
        if self.running:
            print "hi there, everyone!"
            self.master.after(2000, self.execute)

root = Tk()
app = App(root)
root.mainloop()
于 2012-08-23T17:31:17.990 回答