使用消息框在循环后跳出 Python
Break out of a Python after loop using a messagebox
我是 Python 的新手。我这里有这个代码,并试图找到一种方法让消息框跳出 after 循环。有没有办法用我的代码做到这一点,还是我必须以某种方式重写它?
from tkinter import *
import random
from tkinter import messagebox
class Example(Frame):
def __init__(self, parent):
Frame.__init__(self, parent)
self.parent = parent
self.initUI()
def drawBox(self, canvas):
color = hex(random.randrange(4095))[2:6]
l = len(color)
if l == 1:
color = '00' + color
elif l == 2:
color = '0' + color
color = '#' + color
canvas.create_rectangle(100,100,200,200,fill=color)
canvas.pack()
def updateTimer(self, canvas, flag, timer):
timer = self.after(100, lambda: self.drawBox(canvas))
if flag == True:
print('OK clicked')
self.after_cancel(timer)
return
else:
flag = False
self.after(100, lambda: self.updateTimer(canvas, flag, timer))
def initUI(self):
self.parent.title('after_cancel test')
self.pack(fill=BOTH, expand=1)
canvas = Canvas(self)
self.flag = False
timer = self.after(100, lambda: self.updateTimer(canvas, self.flag, timer))
if messagebox.askokcancel('Turn that thing off','Click OK to stop'):
self.updateTimer(canvas, True, timer)
def main():
root = Tk()
root.geometry("300x250+300+300")
app = Example(root)
root.mainloop()
if __name__ == '__main__':
main()
谢谢!
您正在取消对 self.drawBox(...)
的 after
调用,但由于您仍在让 self.updateTimer
运行,循环继续。您应该使用
取消对 self.updateTimer
的下一次调用
self.after_id = self.after(100, lambda: self.updateTimer(canvas, flag, timer))
和
self.after_cancel(self.after_id)
实际上,你让这条路变得更难了。您不需要 updateTimer
函数,也不需要传递那么多变量,只需将它们设为 self
的属性即可。您还在每个循环中创建一个新的 Canvas 和一个新的矩形。这不是必需的,只需更改矩形的颜色即可。
简化代码:
from tkinter import *
import random
from tkinter import messagebox
class Example(Frame):
def __init__(self, parent):
Frame.__init__(self, parent)
self.parent = parent
self.initUI()
def drawBox(self):
color = hex(random.randrange(4095))[2:6]
color = '#' + color.zfill(3)
self.canvas.itemconfig(self.rect, fill=color)
self.after_id = self.after(100, self.drawBox)
def initUI(self):
self.parent.title('after_cancel test')
self.pack(fill=BOTH, expand=1)
self.canvas = Canvas(self)
self.rect = self.canvas.create_rectangle(100,100,200,200,fill='red')
self.canvas.pack()
self.drawBox()
if messagebox.askokcancel('Turn that thing off','Click OK to stop'):
print('OK clicked')
self.after_cancel(self.after_id)
def main():
root = Tk()
root.geometry("300x250+300+300")
app = Example(root)
root.mainloop()
if __name__ == '__main__':
main()
我是 Python 的新手。我这里有这个代码,并试图找到一种方法让消息框跳出 after 循环。有没有办法用我的代码做到这一点,还是我必须以某种方式重写它?
from tkinter import *
import random
from tkinter import messagebox
class Example(Frame):
def __init__(self, parent):
Frame.__init__(self, parent)
self.parent = parent
self.initUI()
def drawBox(self, canvas):
color = hex(random.randrange(4095))[2:6]
l = len(color)
if l == 1:
color = '00' + color
elif l == 2:
color = '0' + color
color = '#' + color
canvas.create_rectangle(100,100,200,200,fill=color)
canvas.pack()
def updateTimer(self, canvas, flag, timer):
timer = self.after(100, lambda: self.drawBox(canvas))
if flag == True:
print('OK clicked')
self.after_cancel(timer)
return
else:
flag = False
self.after(100, lambda: self.updateTimer(canvas, flag, timer))
def initUI(self):
self.parent.title('after_cancel test')
self.pack(fill=BOTH, expand=1)
canvas = Canvas(self)
self.flag = False
timer = self.after(100, lambda: self.updateTimer(canvas, self.flag, timer))
if messagebox.askokcancel('Turn that thing off','Click OK to stop'):
self.updateTimer(canvas, True, timer)
def main():
root = Tk()
root.geometry("300x250+300+300")
app = Example(root)
root.mainloop()
if __name__ == '__main__':
main()
谢谢!
您正在取消对 self.drawBox(...)
的 after
调用,但由于您仍在让 self.updateTimer
运行,循环继续。您应该使用
self.updateTimer
的下一次调用
self.after_id = self.after(100, lambda: self.updateTimer(canvas, flag, timer))
和
self.after_cancel(self.after_id)
实际上,你让这条路变得更难了。您不需要 updateTimer
函数,也不需要传递那么多变量,只需将它们设为 self
的属性即可。您还在每个循环中创建一个新的 Canvas 和一个新的矩形。这不是必需的,只需更改矩形的颜色即可。
简化代码:
from tkinter import *
import random
from tkinter import messagebox
class Example(Frame):
def __init__(self, parent):
Frame.__init__(self, parent)
self.parent = parent
self.initUI()
def drawBox(self):
color = hex(random.randrange(4095))[2:6]
color = '#' + color.zfill(3)
self.canvas.itemconfig(self.rect, fill=color)
self.after_id = self.after(100, self.drawBox)
def initUI(self):
self.parent.title('after_cancel test')
self.pack(fill=BOTH, expand=1)
self.canvas = Canvas(self)
self.rect = self.canvas.create_rectangle(100,100,200,200,fill='red')
self.canvas.pack()
self.drawBox()
if messagebox.askokcancel('Turn that thing off','Click OK to stop'):
print('OK clicked')
self.after_cancel(self.after_id)
def main():
root = Tk()
root.geometry("300x250+300+300")
app = Example(root)
root.mainloop()
if __name__ == '__main__':
main()