Seite 1 von 1
Textausgabe mit automatischen Scrollen
Verfasst: Montag 25. Januar 2021, 19:40
von Epidauros
Hallo zusammen,
ich baue eine SW, die in einem Fenster Aktionen mit Buttons auslöst, und Printausgaben (da können einige hundert Zeilen zusammenkommen) in einem zweiten Fenster. Ich brauche das zweite Fenster, weil das Programm kompiliert werden soll.
Soweit ist auch alles gut und es läuft wie geplant. Fast.
Der Punkt ist: wenn das zweite Fenster voll geschrieben ist und die nächste Zeile wird ausgegeben, dann scrollt der Inhalt im Fenster nicht hoch. Neue Zeilen sind daher nicht lesbar.
Ich benötige eine Konfiguration, die im Fenster immer die letzten ausgegebenen Zeilen durch hochschieben anzeigt.
Ich habe keine Option gefunden, die die Zeilen dann nach oben schiebt.
Code: Alles auswählen
ausgabe = tk.Toplevel()
ausgabe.title("Ausgabefenster")
ausgabe.geometry("350x680")
ausgabe.configure(bg='ivory')
WIN_XPOS = 980
WIN_YPOS = 00
ausgabe.geometry('+{0}+{1}'.format(WIN_XPOS, WIN_YPOS))
label = Label(ausgabe, text=ph+"Informationen und Anzeige der Kommunikation", justify=LEFT)
label.pack()
info=("Die folgenden sds.ini Parameter wurden geladen:\nPause zwischen Durchführungen [s]: "
+str(Pause_Default)+"\nPause zwischen zwei Kommandos [ms]: "
+str(Pause_AT)+"\nAnzahl Durchführungen: "
+str(Durchführungen)+"\nProtocol Identifier: "
+str(PID)+"\nSSI: "
+str(ssi_default))
out = Label(ausgabe, text = info, justify=LEFT)
out.pack()
Re: Textausgabe mit automatischen Scrollen
Verfasst: Montag 25. Januar 2021, 20:01
von noisefloor
Hallo,
bei StackOverflow gibt es schon so eine Frage mit passender Antwort:
https://stackoverflow.com/questions/306 ... n-text-box.
Gruß, noisefloor
Re: Textausgabe mit automatischen Scrollen
Verfasst: Montag 25. Januar 2021, 22:20
von __blackjack__
@Epidauros: Anmerkungen zum gezeigten Quelltext: Kryptische Abkürzungen in Namen sind keine gute Idee. Noch weniger Namen die ausschliesslich aus einer Kryptischen Abkürzung bestehen. Wenn man `parkhaus` meint, sollte man nicht nur `ph` schreiben.
Das zusammenstückeln von Zeichenketten und Werten mittels ``+`` und `str()` ist eher BASIC als Python. Dafür gibt es die `format()`-Methode auf Zeichenketten und f-Zeichenkettenliterale.
`PID` ist auch kein guter Name wenn er nicht für Prozess-ID steht.
Wo kommen `Label` und `LEFT` her wenn `Toplevel` über `tk` angesprochen wird?
Code: Alles auswählen
WIN_XPOS = 980
WIN_YPOS = 0
...
ausgabefenster = tk.Toplevel()
ausgabefenster.title("Ausgabefenster")
ausgabefenster.geometry("350x680")
ausgabefenster.configure(bg="ivory")
ausgabefenster.geometry(f"+{WIN_XPOS}+{WIN_YPOS}")
tk.Label(
ausgabefenster,
text=parkhaus + "Informationen und Anzeige der Kommunikation",
justify=tk.LEFT,
).pack()
tk.Label(
ausgabefenster,
text=(
f"Die folgenden sds.ini Parameter wurden geladen:\n"
f"Pause zwischen Durchführungen [s]: {iteration_pause}\n"
f"Pause zwischen zwei Kommandos [ms]: {command_pause}\n"
f"Anzahl Durchführungen: {iteration_count}\n"
f"Protocol Identifier: {protocol_id}\n"
f"SSI: {default_ssi}"
),
justify=tk.LEFT,
).pack()
Re: Textausgabe mit automatischen Scrollen
Verfasst: Dienstag 26. Januar 2021, 09:18
von Epidauros
Danke! Tut hervorragend!
Auf diesen f String bin ich bisher noch nicht gestossen.
Das einzige, was mich noch stört, ist, dass durch \n getrennte Zeilen zentriert sind, so dass die längste Zeile die Lage der kürzeren Zeilen bestimmt, die dann linksbündig unter der längsten Zeile stehen. Ich hätte gerne alle Zeilen gleich linksbündig am Fenster ausgerichtet. Derzeit behelfe ich mich mittels Parkhaus (:-)), da schicke ich ein "------------------------------------------------------------", und das bestimmt dann die Breite, unterhalb dessen alles linksbündig ausgegeben wird. Nicht schön, ich weiß. Aber ich weiß nicht wie sonst.
Re: Textausgabe mit automatischen Scrollen
Verfasst: Dienstag 26. Januar 2021, 11:02
von __blackjack__
@Epidauros: Das verstehe ich nicht so ganz, denn dafür ist doch das ``justify=tk.LEFT`` da‽
Re: Textausgabe mit automatischen Scrollen
Verfasst: Dienstag 26. Januar 2021, 11:06
von Epidauros
@__blckjack__
das dachte ich auch, aber es kommt anders als man denkt.
Inzwischen habe ich eine andere Methode gefunden, die mir das erledigt.
Dadurch wird immer linksbündig ausgegeben:
Code: Alles auswählen
ausgabe = tk.Toplevel()
S = tk.Scrollbar(ausgabe)
T = tk.Text(ausgabe, height=40, width=50)
S.pack(side=tk.RIGHT, fill=tk.Y)
T.pack(side=tk.LEFT, fill=tk.Y)
S.config(command=T.yview)
T.config(yscrollcommand=S.set)
quote="Mein Text"
T.insert(tk.END, quote)
T.see("end")
Re: Textausgabe mit automatischen Scrollen
Verfasst: Dienstag 26. Januar 2021, 11:06
von Epidauros
@__blckjack__
das dachte ich auch, aber es kommt anders als man denkt.
Inzwischen habe ich eine andere Methode gefunden, die mir das erledigt.
Dadurch wird immer linksbündig ausgegeben:
Code: Alles auswählen
ausgabe = tk.Toplevel()
S = tk.Scrollbar(ausgabe)
T = tk.Text(ausgabe, height=40, width=50)
S.pack(side=tk.RIGHT, fill=tk.Y)
T.pack(side=tk.LEFT, fill=tk.Y)
S.config(command=T.yview)
T.config(yscrollcommand=S.set)
quote="Mein Text"
T.insert(tk.END, quote)
T.see("end")
Re: Textausgabe mit automatischen Scrollen
Verfasst: Dienstag 26. Januar 2021, 16:02
von Epidauros
Hallo zusammen,
Danke noch einmal für die tolle Hilfe.
Jetzt gibt es aber doch noch ein Problem: Ich habe ein Hauptfenster mit Buttons zur Bedienung der Anwendung, und ein Toplevel Fenster mit den Ausgaben, das auch prima scrollt. Aber: Während die nachfolgend dargestellte Aufgabe in einer Schleife läuft, wird nichts im Ausgabefenster ausgegeben. Erst dann, wenn die die Schleifen beendet sind, werden die Ausgaben "nachgeschoben", obwohl die Ausgaben in den Schleifen eingebunden sind
# Hauptfenster
fenster = tk.Tk()
fenster.title("Display-SDS (Autor: DIN)")
WIN_XPOS = 0
WIN_YPOS = 0
fenster.geometry(f"+{WIN_XPOS}+{WIN_YPOS}")
# Ausgabefenster
ausgabefenster = tk.Toplevel()
ausgabe_XPOS=930
ausgabe_YPOS=0
S = tk.Scrollbar(ausgabefenster)
T = tk.Text(ausgabefenster, height=40, width=50)
ausgabefenster.geometry(f"+{ausgabe_XPOS}+{ausgabe_YPOS}")
S.pack(side=tk.RIGHT, fill=tk.Y)
T.pack(side=tk.LEFT, fill=tk.Y)
S.config(command=T.yview)
T.config(yscrollcommand=S.set)
quote="Informationen und Anzeige der Kommunikation"
T.insert(tk.END, quote)
T.see("end")
def dokumentiere(info): # Ausgabe in Ausgabefenster (Toplevel)
quote=f"\n\n"
T.insert(tk.END, quote)
quote=f"\n{info}"
T.insert(tk.END, info)
T.see("end")
def Wiederholung(Durchführungen, Pause_Status): # Durchführungen der Sequenz
wdh=Durchführungen.get()
wdh=int(wdh)
gesamtanzahl = wdh
Durchlauf = 1
print("Durchführung", Durchlauf, "folgt:")
info=(
f"{ph}\n"
f"Durchführung {Durchlauf} folgt:\n")
dokumentiere(info) # Ausgabe in Toplevel Fenster
status_versand(wdh, Pause_Status)
wdh=wdh-1
while wdh != 0:
wdh = wdh-1
Durchlauf = Durchlauf+1
print()
print("------------------------------------")
print()
print("Durchführung", Durchlauf, "folgt:")
info=(
f"{ph}\n"
f"Durchführung {Durchlauf} folgt:\n")
dokumentiere(info) # Ausgabe in Toplevel Fenster
time.sleep(Pause_AT)
status_versand(wdh, Pause_Status)
Re: Textausgabe mit automatischen Scrollen
Verfasst: Dienstag 26. Januar 2021, 16:19
von __blackjack__
@Epidauros: In GUI-Code darfst Du nichts langlaufendes machen. Denn wenn Dein Code läuft, dann wird die GUI nicht aktualisiert. Also so etwas wie längere Schleifen und/oder `time.sleep()` geht nicht. Die GUI friert ein, und Änderungen werden erst sichtbar wenn die GUI-Hauptschleife die Kontrolle wieder hat.
Also entweder kannst Du Deinen Code in kleine, kurze Schritte aufteilen und die mit der `after()`-Methode ausführen, oder das muss in einen eigenen Thread. `after()` braucht man dann auch, weil man aus einem anderen Thread heraus nichts an der GUI ändern darf. Das löst man dann mit einer Queue wo der Thread Informationen rein steckt die regelmässig mit `after()` und einer Funktion da heraus genommen und in die Anzeige gesteckt werden.
Re: Textausgabe mit automatischen Scrollen
Verfasst: Donnerstag 28. Januar 2021, 08:02
von Epidauros
Hallo Blackjack,
Vielen Dank für deine Ausführungen! Das mit dem einfrieren des Fensters habe ich auch schon festgestellt. Zuerst dachte ich, das wäre ein Bug. Aber anscheinend ist das wohl so zu erwarten.
Mit Threads habe ich noch nie gearbeitet.
Könntest du in meinem Codeschnipsel dazu einen Vorschlag zeigen? Das wäre echt super!