我的问题与此类似: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()
答案 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()