2015-03-31 4 views
0

Я новичок в Python. У меня есть этот код здесь и пытался найти способ вывести окно сообщения из цикла после. Есть ли способ сделать это с моим кодом, или мне нужно как-то переписать его?Выйти из цикла Python после цикла с помощью ящика сообщений

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

Спасибо!

ответ

2

Вы отменяете звонок after на номер self.drawBox(...), но поскольку вы все еще пропускаете self.updateTimer, цикл продолжается. Вы должны отменить следующий вызов self.updateTimer с

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

и

self.after_cancel(self.after_id) 

На самом деле, вы делаете этот путь сложнее, чем это. Вам не нужна функция updateTimer, и вам безразлично не нужно передавать так много переменных, просто введите им атрибуты self. Вы также создаете новый холст и новый прямоугольник в каждом цикле. Это необязательно, просто измените цвет прямоугольника.

упрощенный код:

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

Спасибо! Я не понимал, что о создании нового холста в каждом цикле. Я должен это посмотреть. Бесконечно благодарен! – ueH84hGHe88

+0

Ой, подождите, я понимаю, что это не совсем так. Вы не создаете новый холст каждый раз, вы просто собираете его каждый раз, что просто лишнее. Тем не менее вы создавали новый прямоугольник. – fhdrsdg

+0

Кроме того, если ответ разрешил ваш вопрос, вы можете показать, что [принимаете его] (http://meta.stackexchange.com/q/5234/276063). – fhdrsdg