Text.insert(END, 'bla bla') in for-Schleife wird nicht aktualisiert

Fragen zu Tkinter.
Antworten
noobee
User
Beiträge: 2
Registriert: Samstag 8. August 2020, 19:22

Hallo @ community,

in meinem ersten python3-Programm habe ich ein kleines Problem mit tkinter und einem Textfield.

Ich habe etwas (sehr) verschachtelt in vielen for-Schleifen und if-Abfragen zu guter letzt eine Anweisung, mein textfield1 mit Text zu befüllen. Google sagt, dies geschieht mittels

Code: Alles auswählen

Text.insert(END, 'bla bla')
bzw.

Code: Alles auswählen

Text.insert(INSERT, 'bla bla')
. Beides geht nicht. Das textfield1 bleibt leer. Der Code läuft aber, da ich mir zum Abgleich die Ausgabe mittels

Code: Alles auswählen

print('bla bla')
mitplotte.

Erstellt wird es so:

Code: Alles auswählen

textfield1 = Text(app, height=10, width=50)
textfield1.place(x=10, y=40)
und in meiner Funktion start_reading(), die mittels button aufgerufen wird, steht der Code zum aktualisieren des textfield1:
button:

Code: Alles auswählen

button1=Button(app, text='starten', command=start_reading)
button1.place(x=10, y=570, width=100, height=20)
Benutzeravatar
sparrow
User
Beiträge: 4195
Registriert: Freitag 17. April 2009, 10:28

Deine Codeschnipsel weisen darauf hin, dass du einen *-Import verwendest. Das sollte man nicht tun. Gerade mit tkinter holst du dir damit hunderte von Namen in den Namensraum. In der Regel importiert man tkinter so:

Code: Alles auswählen

import tkinter as tk
und greift dann mittels tk. auf die Funktionen, Klassen und Konstanten des Moduls zu.

Wenn du ein Textfeld an den Namen textfield1 bindest, dann musst du auf der Instanz mit dem Namen auch die entsprechende Methode aufrufen. Also

Code: Alles auswählen

textfield1.insert(...)
Wobei textfield1 ein schlechter Name ist. Gewöhne dir gleich an sprechende Namen zu verwenden.
noobee
User
Beiträge: 2
Registriert: Samstag 8. August 2020, 19:22

sparrow hat geschrieben: Samstag 8. August 2020, 21:46 Deine Codeschnipsel weisen darauf hin, dass du einen *-Import verwendest. Das sollte man nicht tun. Gerade mit tkinter holst du dir damit hunderte von Namen in den Namensraum. In der Regel importiert man tkinter so:

Code: Alles auswählen

import tkinter as tk
und greift dann mittels tk. auf die Funktionen, Klassen und Konstanten des Moduls zu.
In der Tat habe ich das getan ;) ich hab mal alles "korrigiert" und mittels "tk." eingebunden. Danke dafür
sparrow hat geschrieben: Samstag 8. August 2020, 21:46Wenn du ein Textfeld an den Namen textfield1 bindest, dann musst du auf der Instanz mit dem Namen auch die entsprechende Methode aufrufen. Also

Code: Alles auswählen

textfield1.insert(...)
Leider geht das textfield1.insert(1.0, 'mein text') immer noch nicht. Oder korrekter gesagt: Mein Textfield wird zwar befüllt, aber erst wenn alle for-Schleifen zu Ende sind. Es soll aber natürlich dann befüllt werden, wenn ich es aufrufe. Muss ich da noch was beachten?
Benutzeravatar
__blackjack__
User
Beiträge: 13116
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@noobee:Wahrscheinlich das übliche: Man darf in GUI-Code keine lang laufenden Schleifen haben, denn solange Deine Schleife läuft, läuft die `mainloop()` nicht und *die* sorgt dafür das die GUI aktuell gehalten und Ereignisse verarbeitet werden. Die `start_reading()`-Funktion darf also nur kurz etwas tun und muss möglichst zeitnah die Kontrolle wieder an die Tk-Hauptschleife zurückgeben von der sie aufgerufen wurde.

Je nach dem was Du machen willst reicht es den Codeablauf der Schleife in kleine Häppchen aufzuteilen deren Ausführung per `after()`-Methode angestossen werden. Oder man muss den Code in einen eigenen Thread auslagern und die Ergebnisse in eine `queue.Queue` stecken und die per `after()` regelmässig nach Daten abfragen.

Für jede nicht-triviale GUI braucht man objektorientierte Programmierung. Das scheinst Du auch noch nicht zu machen, sondern Variablen auf Modulebene und ”Funktionen” zu verwenden. Auf Modulebene sollte nur Code stehen der Konstanten, Funktionen, und Klassen definiert. Das Hauptprogramm steht üblicherweise in einer Funktion die `main()` heisst. Funktionen und Methoden bekommen alles was sie ausser Konstanten benötigen als Argument(e) übergeben.

`place()`, also absolute Positionen (und Grössen) verwendet man nicht. Das mag auf dem Rechner auf dem es entwickelt wurde funktionieren, aber bei den heutigen Variationen von Bildschirmgrössen und -auflösungen kann das auf anderen Rechnern falsch dargestellt werden oder gar unbenutzbar sein.
„All religions are the same: religion is basically guilt, with different holidays.” — Cathy Ladman
Antworten