简体   繁体   English

使用消息框突破Python循环后

[英]Break out of a Python after loop using a messagebox

I'm new to Python. 我是Python的新手。 I have this here code and was trying to find a way to have the message box break out of the after loop. 我在这里有此代码,并试图找到一种使消息框脱离after循环的方法。 Is there a way to do this with my code, or do I have to rewrite it somehow? 有没有办法用我的代码来执行此操作,还是必须以某种方式重写它?

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()

Thanks! 谢谢!

You're cancelling the after call to self.drawBox(...) , but since you're still letting self.updateTimer run, the loop continues. 您正在取消对self.drawBox(...)after调用,但由于仍在运行self.updateTimer ,因此循环将继续。 You should cancel the next call to self.updateTimer with 您应该使用取消对self.updateTimer的下一次调用

self.after_id = self.after(100, lambda: self.updateTimer(canvas, flag, timer))

and

self.after_cancel(self.after_id)

Actually, you're making this way harder than it is. 实际上,您正在使这种方法变得更困难。 You don't need the updateTimer function and you defenitely don't need to pass around so many variables, just make them attributes of self . 您不需要updateTimer函数,当然也不需要传递这么多的变量,只需将它们设置为self属性即可。 You're also creating a new Canvas and a new rectangle every loop. 您还将在每个循环中创建一个新的Canvas和一个新的矩形。 This is not necessary, simply change the color of the rectangle. 不必这样做,只需更改矩形的颜色即可。

Simplified code: 简化代码:

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()  

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM