2012-05-15 646 views
6

Soy bastante nuevo en Python y quiero establecer una etiqueta en Tkinter usando mi función de cuenta atrás. En este momento todo lo que hace es establecer la etiqueta en "10" una vez que se alcanza el 10 y realmente no entiendo por qué. Además, incluso si tengo el temporizador impreso en un terminal en lugar de "¡se acabó el tiempo!" poco nunca se imprime.Hacer un temporizador de cuenta regresiva con Python y Tkinter?

import time 
import tkinter as tk 

class App(): 
    def __init__(self): 
     self.root = tk.Tk() 
     self.label = tk.Label(text="null") 
     self.label.pack() 
     self.Pomodoro() 
     self.root.mainloop() 

    ## Define a timer. 
    def Pomodoro(self): 
     p = 10.00 
     t = time.time() 
     n = 0 
     while n - t < p: ## Loop while the number of seconds is less than the integer defined in "p" 
      n = time.time() 
      if n == t + p: 
       self.label.configure(text="Time's up!") 
      else: 
       self.label.configure(text=round(n - t)) 

app=App() 

EDIT: Una respuesta anterior mostró que la razón por la que nunca trabajaron "Time's up!" es a causa de lo improbable que era para n para igualar exactamente t + p debido a la imprecisión con el uso de time.time. La versión final basado en la consola del temporizador fue:

import time 

## Define a static Pomodoro timer. 
def Countdown(): 
     p = 2.00 
     alarm = time.time() + p 
     while True: ## Loop infinitely 
      n = time.time() 
      if n < alarm: 
       print(round(alarm - n)) 
      else: 
       print("Time's up!") 
       break 

Countdown() 

Sin embargo, esto no funciona con Tkinter por las razones Bryan Oakley menciona en su respuesta y comentarios.

+0

aquí hay un [ejemplo de código de una cuenta atrás implementado usando Tkinter] (https://gist.github.com/zed/1951815) – jfs

Respuesta

8

Tkinter ya tiene un bucle infinito en ejecución (el bucle de evento) y una manera de programar las cosas para que se ejecuten después de que haya transcurrido un período de tiempo (usando after). Puede aprovechar esto escribiendo una función que se llame una vez por segundo para actualizar la pantalla. Puede usar una variable de clase para realizar un seguimiento del tiempo restante.

import Tkinter as tk 

class ExampleApp(tk.Tk): 
    def __init__(self): 
     tk.Tk.__init__(self) 
     self.label = tk.Label(self, text="", width=10) 
     self.label.pack() 
     self.remaining = 0 
     self.countdown(10) 

    def countdown(self, remaining = None): 
     if remaining is not None: 
      self.remaining = remaining 

     if self.remaining <= 0: 
      self.label.configure(text="time's up!") 
     else: 
      self.label.configure(text="%d" % self.remaining) 
      self.remaining = self.remaining - 1 
      self.after(1000, self.countdown) 

if __name__ == "__main__": 
    app = ExampleApp() 
    app.mainloop() 
+0

Eso explica muchas cosas, gracias. Me preguntaba por qué solo se actualiza una vez que se alcanza el último elemento incluso después de que lo reescribí de diferentes maneras. –

+0

@RyanHasse: la pantalla solo se actualiza cuando Tkinter puede responder a eventos que le dicen que actualice la pantalla. Estos eventos solo son procesados ​​por el ciclo de eventos. Si tiene su propio bucle, morirá de hambre el bucle de eventos, lo que impedirá que vuelvan a suceder las solicitudes. –

Cuestiones relacionadas