Threads in einer Gui beenden nach dem Mainloop

Fragen zu Tkinter.
Antworten
Simon79
User
Beiträge: 5
Registriert: Samstag 30. Oktober 2021, 12:38

Hallo,
Ich habe gerade das Problem, dass ich in einer gui ein Thread auf Endlosschleife habe um netzwerkinformationenc zu empfangen.
Ich habe den thread mit do_run true gemacht. Er schluckt den ausstiegbefehl aber nach dem beenden des mainloops aber nicht. Was mache ich da falsch?
Benutzeravatar
Dennis89
User
Beiträge: 1519
Registriert: Freitag 11. Dezember 2020, 15:13

Hallo,

ich weis nicht wie es anderen geht, aber ohne deinen Code ist es schwer deinen Fehler zu erkennen.
Bitte den Code in Code-Tags posten, das geht mit dem </> - Button.


Grüße
Dennis
"When I got the music, I got a place to go" [Rancid, 1993]
Simon79
User
Beiträge: 5
Registriert: Samstag 30. Oktober 2021, 12:38

<
import threading
import time
import tkinter

def autosave(arg):
t2 = threading.current_thread()
while getattr(t2, "do_run", True):
with open(""+user["name"] + ".csv", "w") as f:
for key in arbeit.keys():
f.write("%s,%s\n" % (key, arbeit[key]))
time.sleep(600)

hauptfenster = tkinter.Tk()
hauptfenster.title("Name")
hauptfenster.geometry("700x500")
hauptfenster.resizable(width=0, height=0)


t2 = threading.Thread(target=autosave, args=("task",))
t2.start()

hauptfenster.mainloop()

t2.do_run = False
/>
Benutzeravatar
Dennis89
User
Beiträge: 1519
Registriert: Freitag 11. Dezember 2020, 15:13

Hallo,

'mainloop' startet dein GUI in einer Schleife, sonst wäre deine Oberfläche wie eingefroren. Das heißt aber auch, das Code, der nach dem 'mainloop'-Aufruf steht nicht ausgeführt wird.

Du musst dafür sorgen das ein Ereignis, wie zum Beispiel das Betätigen eines Buttons, 't2.do_run = False' ausführt.

Dafür solltest du zumindest mit Funktionen arbeiten.

Grüße
Dennis
"When I got the music, I got a place to go" [Rancid, 1993]
Simon79
User
Beiträge: 5
Registriert: Samstag 30. Oktober 2021, 12:38

Super, das hilft mir, dann denke ich ein bisschen darauf rum
Benutzeravatar
Dennis89
User
Beiträge: 1519
Registriert: Freitag 11. Dezember 2020, 15:13

Wann willst du denn den Thread beenden?

Python hat ein csv-Modul, das man zum arbeiten mit csv-Dateien nutzt. Pfade sind eigentlich auch mehr wie Strings. Strings puzzelt man nicht mit '+' zusammen, sondern verwendet f-Strings oder die 'format'-Methode und für Pfade gibt es das 'pathlib' - Modul.

Grüße
Denis
"When I got the music, I got a place to go" [Rancid, 1993]
Sirius3
User
Beiträge: 18253
Registriert: Sonntag 21. Oktober 2012, 17:20

Man packt nicht einfach Attribute zu Instanzen, und fragt sie erst recht nicht so ab. Alles was eine Funktion braucht, muß sie über ihre Argumente bekommen, arbeit ist aber nirgends definiert. Genauso wenig wie user.
Bei Threads sind globale Variablen sogar noch viel schlechter, weil nicht nur der Ort,sondern auch die Zeit des Zugriffs unkontrolliert ist.
Für ein Autosave braucht es auch gar keinen Thread, da reicht ein einfaches after.
Simon79
User
Beiträge: 5
Registriert: Samstag 30. Oktober 2021, 12:38

@dennis89
Ich möchte den thread beenden, wenn das Fenster geschlossen wird. Ich hab es jetzt versucht mit einer Funktion in der Hauptfenster.destroy() enthalten ist und davor sollten die threads beendet werden. Da die sich aber in einem warte Moment befinden bleiben sie und hängen sich auf, wenn sie wieder aktiv werden.
Also muss ich eine Lösung finden, in der die threads aktiv eliminiert werden.

Wegen des pathlib überlege ich auch nochmal. Aber die csv Datei wird da ja erstellt somit werde ich sie wohl nicht finden.

@sirius
Ich kann dir leider nicht folgen. Ich weiss nicht genau was du meinst.
Das ist mein erstes Projekt. Ich hab mir das alles selber beigebracht und bin natürlich über Hilfen sehr dankbar.... Wenn ich sie verstehe 🙈
__deets__
User
Beiträge: 14545
Registriert: Mittwoch 14. Oktober 2015, 14:29

Nur weil man etwas regelmäßig tun will, muss man keine threads benutzen. Und erst recht nicht, wenn man mit GUIs arbeitet, und dein autosave auf GUI-Elemente zugreift. Das können bestenfalls inkonsistente Daten bei rumkommen. Und schlimmstenfalls dein Programm abstürzen. Darum benutz man stattdessen eine Timer, in tkinter mit der after Funktion zu erzeugen.
Simon79
User
Beiträge: 5
Registriert: Samstag 30. Oktober 2021, 12:38

Ok, das macht wenn du es so sagst, macht es sinn. Ich benutze 4 threads. Für das autosave, für zwei permanente Berechnung und eine Empfänger der immer auf das Netzwerk hört. Ich werde dann mal schauen mal wie ich das autosave anders Regel. Wobei ich die permanenten Berechnungen auch zusammenfassen könnte. Dann hätte ich nur noch 2 threads neben dem Main.

Total klasse eure Anstöße. Danke dafür
Antworten