2009-12-16 5 views
14

Je travaille sur l'obtention d'un widget d'étiquette python/tkinter pour mettre à jour son contenu. Par un fil plus tôt aujourd'hui, j'ai suivi des instructions sur la façon de mettre en place les widgets. À l'exécution, cependant, le widget d'étiquette ne change pas le contenu, mais conserve simplement son contenu d'origine. Pour autant que je sache, decrement_widget() n'est jamais appelé du tout. Des idées?Mise à jour du widget d'étiquette python/tkinter?

def snooze (secs): 
    """ 
    Snoozes for the given number of seconds. During the snooze, a progress 
    dialog is launched notifying the 
    """ 

    root = Tkinter.Tk() 
    prompt = 'hello' 
    label1 = Tkinter.Label(root, text=prompt, width=len(prompt)) 
    label1.pack() 

    remaining = secs 

    def decrement_label(): 
    text = "Snoozing %d sec(s)" % remaining 
    remaining -= 1 
    label1.config(text=text, width=100) 
    label1.update_idletasks() 

    for i in range(1, secs + 1): 
    root.after(i * 1000, decrement_label) 

    root.after((i+1) * 1000, lambda : root.destroy()) 
    root.mainloop() 

Répondre

16

Vous souhaitez définir textvariable avec un StringVar de l'étiquette; lorsque les modifications StringVar (en appelant myStringVar.set("text here")), le texte de l'étiquette est également mis à jour. Et oui, je suis d'accord, c'est une façon étrange de faire les choses.

Voir the Tkinter Book pour un peu plus d'informations à ce sujet:

Vous pouvez associer une variable Tkinter avec une étiquette. Lorsque le contenu des modifications variables, l'étiquette est automatiquement mis à jour:

v = StringVar() 
Label(master, textvariable=v).pack() 

v.set("New Text!") 
+0

par votre recommandation, j'ai changé la fonction decrement_label pour « text = ...; reste - = 1; sv = Tkinter.StringVar(); sv.Set (texte); label1.conf (texte = sv, largeur = 100); label1.update_idletasks() '. Cependant, cela n'a eu aucun effet sur le comportement d'exécution. La fonction decrement_label n'a PAS l'air d'être appelée du tout! –

+0

J'ai également compris que l'instruction 'restant - = 1' semble être à l'origine du problème. Python échoue silencieusement quand il rencontre cette déclaration. Y a-t-il quelque chose qui ne va pas? –

+0

Vous devez définir 'StringVar' lorsque vous créez le' Label', puis modifiez cette même instance de 'StringVar'. Vous ne devriez pas avoir besoin d'appeler 'label1.conf' à plusieurs reprises. Postez votre code entièrement mis à jour. –

5

Je pense que vous obtenez une erreur « référencé avant cession » parce que Python pense remaining est dans la portée locale. En Python 3, vous pouvez dire nonlocal remaining. Mais dans Python 2, je ne crois pas qu'il existe un moyen de faire référence à une portée non locale et non globale. Cela a fonctionné pour moi:

remaining = 0 

def snooze (secs): 
    """ 
    Snoozes for the given number of seconds. During the snooze, a progress 
    dialog is launched notifying the 
    """ 

    global remaining 
    root = Tkinter.Tk() 
    prompt = 'hello' 
    label1 = Tkinter.Label(root, text=prompt, width=len(prompt)) 
    label1.pack() 

    remaining = secs 

    def decrement_label(): 
    global remaining 
    text = "Snoozing %d sec(s)" % remaining 
    remaining -= 1 
    label1.config(text=text, width=100) 
    label1.update_idletasks() 

    for i in range(1, secs + 1): 
    root.after(i * 1000, decrement_label) 

    root.after((i+1) * 1000, lambda : root.destroy()) 
    root.mainloop() 
0
import tkinter 
    from tkinter import * 

    # just init some vars 
    remaining = 0     
    secs = 0 
    root = tkinter.Tk() 
    prompt = StringVar() 

    def snooze (secs): 
     """ 
     Snoozes for the given number of seconds. During the snooze, a progress 
     dialog is launched notifying the 
     """ 
     def decrement_label(): 
     global remaining, prompt 
     remaining -= 1 
     prompt.set('Snoozing %d sec(s)' % remaining) 
     label1.update_idletasks() 
     if not remaining: 
      print("end ... ") 
      root.destroy() 

     global remaining 
     prompt.set("hello") 
     label1 = tkinter.Label(root, textvariable=prompt, width=30) 
     label1.pack() 

     remaining = secs 
     for i in range(1, secs + 1): 
     root.after(i * 1000, decrement_label) 

    snooze(10) 
    root.mainloop()