9
votes

Quand j'utilise update () avec tkinter mon label écrit une autre ligne au lieu de réécrire le même texte

Lorsque j'appelle la méthode de mise à jour () à l'aide de Tkinter au lieu de réécrire l'étiquette, il suffit d'écraser l'étiquette dans l'appel précédent. Je voudrais que cela réécrit sur la ligne précédente.

Par exemple: P>

root=Tk()
while True:
    w=Label(root, text = (price, time))
    w.pack()
    root.update()


2 commentaires

Pourriez-vous fournir un exemple de code qui démontre le problème s'il vous plaît?


C'est tout ce dont vous avez besoin pour observer le problème. Mise à jour écrit sous la dernière ligne au lieu de dessus.


5 Réponses :


1
votes

La classe Badroot code> doit démontrer le problème que vous rencontrez. Vous pouvez commenter l'appel à la classe pour vérifier avec un exemple de travail complet. Si vous exécutez le code comme écrit, il mettra à jour l'étiquette dans la classe Goodroot code>. La première ligne commentée montre une autre syntaxe pour modifier le texte de votre étiquette.

from tkinter import Tk, Label
from time import sleep
from random import random

class BadRoot(Tk):

    def __init__(self, price, time):
        super().__init__()
        self.labels = []
        while True:
            self.labels.append(Label(self, text=(price, time)))
            self.labels[-1].pack()
            self.update()
            sleep(1)

class GoodRoot(Tk):

    def __init__(self, callback):
        super().__init__()
        self.label = Label(self, text=str(callback()))
        self.label.pack()
        while True:
##            self.label['text'] = str(callback())
            self.label.configure(text=str(callback()))
            self.update()
            sleep(1)

if __name__ == '__main__':
##    BadRoot('$1.38', '2:37 PM')
    GoodRoot(random)


2 commentaires

@OAKLEY: Avez-vous aimé le code d'origine dans la question de mieux? Il n'y avait pas de pause pour permettre à quelqu'un d'observer et de contempler ce qui se passait. Je pourrais avoir tout aussi facilement utilisé un après appelé dans tkinter au lieu de la fonction de veille .


Non, le code d'origine n'est pas meilleur, si je comprends ce que vous demandez. Quoi qu'il en soit, lorsque vous donnez des réponses à des personnes qui commencent à apprendre à apprendre la programmation de l'interface graphique, vous ne devriez pas donner des exemples qui font des erreurs fondamentales. Au moins, non sans traiter les effets secondaires et les inconvénients dans le cadre de la réponse.



3
votes

Non.

Je soupçonne, sans l'avoir vu, qu'il y a au moins quelques confusions dans le code WDroter a écrit. En général, il n'est pas nécessaire dans un code Tkinter bien structuré d'utiliser la mise à jour () du tout. Voici un petit exemple qui illustre les mises à jour du texte d'une étiquette: xxx

exécuter cela. Appuyez sur le bouton. Chaque fois que vous le faites (tant que vos pousses diffèrent d'au moins une seconde), vous verrez la mise à jour du texte.


2 commentaires

Il est vrai que le bon tkinter ne doit probablement pas appeler mettre à jour , mais cela ne répond pas à la question. C'est parfaitement bien, bien que possible, d'appeler update dans tkinter . Le problème avec le code donné était qu'un nouvel étiquette était créé et emballé dans l'interface à chaque fois par la boucle. Il y a au moins trois solutions au problème: (1) Détruisez l'étiquette à quoi que ce soit Valeur Il devrait avoir, et (3) Lier un StringVar à l'objet Etiquette et modifier sa valeur.


Nous sommes d'accord, Noctis Skytower. Le code d'approvisionnement WDroTer a-t-il fait Je n'ai pas vu ça ("... donnée du code" - où? Ce n'est pas montrant pour moi), et le vôtre seulement après avoir répondu. Je vous salue pour avoir envie de construire vos deux exemples.



13
votes

Votre problème est simplement ceci: lorsque vous faites pendant que true code>, vous créez une boucle infinie. Le code de cette boucle fonctionnera jusqu'à ce que vous forciez le programme à quitter. Dans cette boucle, vous créer em> une étiquette. Ainsi, vous créerez un nombre infini d'étiquettes.

Si vous souhaitez mettre à jour une étiquette de manière régulière, profitez de la boucle infinie déjà exécutée - la boucle d'événement. Vous pouvez utiliser après code> pour planifier une fonction à appeler à l'avenir. Cette fonction peut se reprogrammer à nouveau à exécuter, garantissant qu'il fonctionnera jusqu'à ce que le programme quitte le problème. P>

Voici un exemple simple: P>

import Tkinter as tk
import time

class SampleApp(tk.Tk):
    def __init__(self, *args, **kwargs):
        tk.Tk.__init__(self, *args, **kwargs)
        self.clock = tk.Label(self, text="")
        self.clock.pack()

        # start the clock "ticking"
        self.update_clock()

    def update_clock(self):
        now = time.strftime("%H:%M:%S" , time.gmtime())
        self.clock.configure(text=now)
        # call this function again in one second
        self.after(1000, self.update_clock)

if __name__== "__main__":
    app = SampleApp()
    app.mainloop()


0 commentaires

1
votes

au lieu de w.pack () tu peux écrire w.grid (rangée = 0, colonne = 0)

pack () dans tkinter emballe habituellement des objets dans une seule ligne / colonne. Il dépose des choses le long des côtés d'une boîte. Tandis que, grille () a plus d'une table comme une structure. Donc, lorsque vous écrivez rangée = 0 et colonne = 0 , il n'a aucun choix que de remplacer le précédent s'il existe. Parce que vous avez fourni une position très spécifique au lieu de simplement le pousser à la fenêtre (qui est chapeau pack () fait)


0 commentaires

2
votes

Vous voulez utiliser .configure à la place

while True:
    w.Configure(text = (price, time))
    root.update()


0 commentaires