Forum: PC-Programmierung Python Tkinter in Windows blockiert


Announcement: there is an English version of this forum on EmbDev.net. Posts you create there will be displayed on Mikrocontroller.net and EmbDev.net.
von Philipp K. (philipp_k59)


Lesenswert?

Moin,

ich habe ein kleines Script das auf Linux 1A und lange läuft, aber auf 
Windows Dauerhaften Wartecursor hat und abstürzt.

Frage erstmal wieso in Linux okay, aber auf Windows nicht?

Im Prinzip weiß ich wodran es liegt, das ist eine Endlosschleife 
serial.readLine mit kurzer Verarbeitung und aktualisierung eines 
StringVar() als Vermittler zu Tkinter.

Ich habe mir jetzt mehrere Tutorials und Beispiele für Threads 
angeschaut, aber bei den meisten werden Buttons für aktualisierungen 
etc. verwendet.

wundert mich das es kein fertiges Lernbeispiel dazu gibt.

von M.A. S. (mse2)


Lesenswert?

Philipp K. schrieb:
> ich habe ein kleines Script das auf Linux 1A und lange läuft, aber auf
> Windows Dauerhaften Wartecursor hat und abstürzt.

Falls hier jemand mitliest, der theoretisch antworten könnte, hätte 
dieser es sicher einfacher, könnte er einen Blick auf besagtes Skript 
werfen, meinst Du nicht?!

: Bearbeitet durch User
von Philipp K. (philipp_k59)


Angehängte Dateien:

Lesenswert?

M.A. S. schrieb:
> meinst Du nicht?!

ich meine wer das Problem nicht versteht wird mir zu 99% auch nicht 
helfen können.. da ich das absolut minimert habe und es dort auch 
passiert.

Minimalversion im Anhang.

von Dirk B. (dirkb2)


Lesenswert?

Philipp K. schrieb:
1
while TRUE:
2
    try:
3
       cc=str(ser.readline())
4
    except: True
5
    c=c+1
6
    varo.set(c)
7
    print(c)
8
    root.update_idletasks()
9
10
root.mainLoop()
Wenn ser  blockierend ist, dann wird root.update_idletasks() niemals 
ausgeführt.

root.mainLoop() wird nie ausgeführt, da die while-Schleife nicht beendet 
wird.

Benutze für ser einen event-Handler, der die Funktion der while-Schleife 
übernimmt.
Der wird immer dann aufgerufen, wenn Daten auf ser anliegen.

von Philipp K. (philipp_k59)


Lesenswert?

Okay danke, dann ist pyserial auf Windows wohl blockierend, die App 
selber muss auch nur Updaten wenn jede Sekunde etwas serielles ankommt.

Auf Linux funktioniert das auch, Windows erkennt das wohl als nicht 
antwortendes Fenster und will die App schliessen, bzw. Freezt den 
Prozess.

von Hmmm (Gast)


Lesenswert?

Philipp K. schrieb:
> Okay danke, dann ist pyserial auf Windows wohl blockierend

Eigentlich sollte readline() prinzipbedingt blocken, bis ein Newline 
empfangen wird, sofern Du nicht beim Öffnen des Ports einen Timeout 
setzt.

Philipp K. schrieb:
> Auf Linux funktioniert das auch, Windows erkennt das wohl als nicht
> antwortendes Fenster und will die App schliessen, bzw. Freezt den
> Prozess.

Windows mag es nicht, wenn eine GUI-Anwendung keine Window Messages mehr 
verarbeitet. Deshalb sollte man alles, was länger braucht, in einen 
separaten Thread packen.

von Philipp K. (philipp_k59)


Lesenswert?

Okay Danke, ich habe es dann mit Threads irgendwie hinbekommen.

von Εrnst B. (ernst)


Lesenswert?

Der "Old School" - Weg ohne Threads wäre gewesen, in der mainLoop neben 
GUI-Events eben auch auf Socket/Serial-Port-Events zu warten&reagieren.

in C gäb's dazu "Tcl_CreateFileHandler"

im Python sollte das mit

tkinter.createfilehandler(ser, tkinter.READABLE, handle_serial_data)

umgesetzt sein.

https://docs.python.org/3.3/faq/gui.html#can-i-have-tk-events-handled-while-waiting-for-i-o

von Philipp K. (philipp_k59)


Lesenswert?

Εrnst B. schrieb:
> in der mainLoop neben GUI-Events eben auch auf Socket/Serial-Port-Events
> zu warten&reagieren.

Das ist auch ein interessanter Ansatz.

von Εrnst B. (ernst)


Lesenswert?

Philipp K. schrieb:
> Das ist auch ein interessanter Ansatz.

Kann aber gut sein, dass das unter Windows eh nicht geht, unter Unix 
wird das Serial-Port-File-Handle dann einfach in dasselbe select/poll 
gepackt wie das X11-Socket.
Unter Windows: ?

: Bearbeitet durch User
von Dirk B. (dirkb2)


Lesenswert?

Εrnst B. schrieb:
> Philipp K. schrieb:
>> Das ist auch ein interessanter Ansatz.
>
> Kann aber gut sein, dass das unter Windows eh nicht geht, unter Unix
> wird das Serial-Port-File-Handle dann einfach in dasselbe select/poll
> gepackt wie das X11-Socket.
> Unter Windows: ?

Das liegt dann aber am Verhältnis von tkinter(Python) mit Windows.
Bei Tcl/Tk unter Windows klappt das nämlich.

von Philipp K. (philipp_k59)


Lesenswert?

Εrnst B. schrieb:
> Unter Windows: ?

Werden wahrscheinlich File orrientierte Sockets nicht unterstützt da 
nicht vorhanden..

Vielleicht sieht es irgendwann mit WSL etc. etwas anders aus.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.