Tkinter label akruallisieren

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
toper3902

Hallo zusammen. Ich versuche gerade mit Tkinter ein Programm zu schreiben das mir einen Countdown anzeigt.
Allerdings aktuallisiert sich das Label nicht

Code: Alles auswählen

import time
import datetime
from tkinter import *



endzeit = 1627732800
while True:
    window = Tk()
    
    jetzt = time.time()
    differenz = round(endzeit - jetzt)

    label = Label(master=window,font=("Arial",40),text = differenz,width = 30,height=5)
    label.pack()
    window.mainloop()
Benutzeravatar
__blackjack__
User
Beiträge: 14034
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@toper3902: Nein, natürlich nicht, denn da steht ja nirgends Code der das Label aktualisieren würde. Du erstellst immer wieder neue Fenster in einer Endlosschleife. Die aber in der letzten Zeile des Schleifenkörpers immer wartet bis der `mainloop()`-Aufruf zurückkehrt. Also wenn der Benutzer das Fenster schliesst.

Du importierst `datetime`, verwendest es aber nicht. Obwohl damit hier wahrscheinlich lesbarerer Code zustande käme als mit `time` und ”magischen” Zahlen wie 1627732800.

Sternchen-Importe sind Böse™. Du holst damit alle Namen aus dem `tkinter`-Modul in Dein Modul und verwendest nur einen ganz kleinen Bruchteil davon. Bei solchen Importen besteht auch immer die Gefahr von Namenskollisionen.

Auf Modulebene sollte nur Code stehen, der Konstanten, Funktionen, und Klassen definiert. Keine Variablen! Das Hauptprogramm steht üblicherweise in einer Funktion die `main()` heisst.

GUI-Programmierung funktioniert nicht so wie Deine ``while``-Schleife suggeriert. GUI-Programmierung ist ereignisorientiert. Das heisst Du hast nicht mehr die Kontrolle über den Programmablauf, sondern die GUI-Hauptschleife. Du kannst Rückruffunktionen registrieren die bei bestimmten Ereignissen von der GUI-Hauptschleife aufgerufen werden und dann *kurz* etwas machen dürfen bevor sie die Kontrolle an die GUI-Hauptschleife wieder zurückgeben. Beispiele für solche Ereignisse kann der Klick des Benutzers auf eine Schaltfläche sein, aber auch das eine bestimmte Zeit verstrichen ist. Für letzteres gibt es die `after()`-Methode auf Widgets.

Und bei jedem nicht-trivialen GUI-Programm kommt man um objektorientierte Programmierung nicht wirklich drum herum. In diesem Beispiel geht das gerade noch so, weil man die nötigen Argumente alle der Rückruffunktion zur Aktualisierung des Labels mitgeben kann, welche die dann an `after()` für den nächsten Aufruf mitgeben kann.
„A life is like a garden. Perfect moments can be had, but not preserved, except in memory. LLAP” — Leonard Nimoy's last tweet.
toper3902

Also erstmal danke für die Tipps,
aber wie soll ich das es Funktioniert?
Benutzeravatar
__blackjack__
User
Beiträge: 14034
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@toper3902: Naja, eben mit der `after()`-Methode. Da sollte es einige Beispiele hier im Forum geben, inklusive Countdowns.

Allerdings könntest Du auch überlegen erst einmal die Grundlagen zu lernen, bevor Du mit GUI-Programmierung weiter machst, denn bei GUIs muss man so ziemlich alle auf einmal lernen, also inklusive objektorientierter Programmierung *und* dann bei der GUI-Programmierung noch das Ereignisbasierte. Klassen setzen Funktionen voraus, und in Funktionen braucht man ein grundlegendes Verständnis vom Programmablauf, zum Beispiel bei Schleifen. Und selbst da zeigt Dein Code das Du das mit der Abarbeitungsreihenfolge noch nicht so ganz verstanden haben kannst, wenn Du in einer Endlosschleife immer neue *Fenster* erstellen möchtest um ein Label zu aktualisieren.
„A life is like a garden. Perfect moments can be had, but not preserved, except in memory. LLAP” — Leonard Nimoy's last tweet.
Antworten