Echtzeit-Ausgabe im Fenster

Fragen zu Tkinter.
Antworten
Matzward56
User
Beiträge: 2
Registriert: Sonntag 24. Januar 2021, 17:54

Bin alter FORTRAN-Mensch, und ich tue mich etwas schwer in Python. Habe alte Programme mit langen Laufzeiten, die ich umschreiben möchte. Es soll in einem Fenster in Echtzeit, z. B. alle Stunden, eine Information ausgegeben werden wie bei "print", und nicht erst am Ende des mainloops wie in tkinter in folgendem Beispiel:

Code: Alles auswählen

 
 import  tkinter.scrolledtext
import time
#
def xshow():
    for i in range(5):
        lt=time.localtime()
        stunde,minute,sekunde = lt[3:6]
        text=f"Uhrzeit: {stunde:02d}:{minute:02d}:{sekunde:02d}"
        t.insert("end",text+"\n")
        time.sleep(30)
        #
main=tkinter.Tk()
t=tkinter.scrolledtext.ScrolledText(main,width=40,height=10)
t.pack()
bshow=tkinter.Button(main,text="Starten",command=xshow)
bshow.pack()
main.mainloop      
  
gibt es bei t.insert Möglichkeiten der Echtzeitausgabe ? Ein Literaturhinweis würde mir reichen.
__deets__
User
Beiträge: 14545
Registriert: Mittwoch 14. Oktober 2015, 14:29

Die Lösung in tkinter wäre ein thread für die Arbeit & ein After-basierter Timer callback, der periodisch den Zustand des worker-Threads kommuniziert. Sowas wurde hier schon oft besprochen, after, thread & queue sind Stichworte.

Alternativ kann pygame schleifen-basierte Darstellung, ist aber keine GUI in dem Sinne.
Sirius3
User
Beiträge: 18289
Registriert: Sonntag 21. Oktober 2012, 17:20

`mainloop` muß man auch aufrufen.
Statt time.localtime benutzt man datetime.datetime.now.
Alles was eine Funktion braucht, muß sie über ihre Argumente bekommen.
Langlaufende Funktionen darf es bei GUIs nicht geben, weshalb man Funktionen zeitgesteuert immer wieder aufrufen muß.

Code: Alles auswählen

import tkinter.scrolledtext
import datetime
from functools import partial

def xshow(text_field):
    now = datetime.datetime.now()
    text = f"Uhrzeit: {now:%H:%M:%S}\n"
    text_field.insert("end", text)
    text_field.after(30000, xshow, text_field)

def main():
    root = tkinter.Tk()
    text_field = tkinter.scrolledtext.ScrolledText(root, width=40, height=10)
    text_field.pack()
    button_show=tkinter.Button(root, text="Starten", command=partial(xshow, text_field))
    button_show.pack()
    root.mainloop()
    
if __name__ == '__main__':
    main()
Wenn man dann noch einen Code hat, der tatsächlich rechenintensiv ist, braucht man einen eigenen Thread, in dem die Rechnung läuft und Statusmeldungen per Queue an die GUI übergibt.
Diese Frage kommt alle zwei Wochen hier im Forum. Einfach ein bißchen suchen.
Matzward56
User
Beiträge: 2
Registriert: Sonntag 24. Januar 2021, 17:54

Danke, das hat mir schon geholfen. Ich hatte gedacht, ich hätte etwas übersehen. Jetzt werde ich mich mit threads beschäftigen.
Antworten