Tkinter多个操作

时间:2012-08-23 17:16:01

标签: python user-interface button tkinter frame

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

我的问题:我的框架上有两个按钮。只要toggle变量设置为true,一个按钮就会调用'execute'函数。第二个按钮将切换值设置为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()

1 个答案:

答案 0 :(得分:4)

简短的回答,你无法做到你想要的。 Tkinter是单线程的 - 当你调用sleep(2)时,它完全符合你的要求:它会睡觉。

如果您的目标是每2秒执行一次,只要布尔标志设置为True,您就可以使用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()