WildWilli

Fragen zu Tkinter.
Antworten
WildWilli
User
Beiträge: 3
Registriert: Samstag 4. Februar 2017, 00:56

Hi,
aus meinem Hauptprogramm (Python) soll bei jedem Durchlauf ein Fenster Aktualisiert werden welches z Bsp. per Checkbox den Zustand der GPIOs anzeigt (Raspberry Pi 3b)
das Hauptprogramm läuft ohne Probleme aber die GUI bekomme ich nicht mal im Ansatz hin :K
BlackJack

@WildWilli: Der Wunsch/Ansatz ist schon falsch. Wenn Du eine GUI programmierst, dann ist *die* das Hauptprogramm. Die GUI-Hauptschleife bestimmt den Programmablauf.

Wenn Du den Zustand ”pollst” und das zügig geht, kannst Du beispielsweise eine entsprechende Funktion/Methode per `after_idle()` auf Anzeigeelementen aufrufen lassen und das immer wieder. Oder mit `after()` eine gewisse Wartezeit einbauen.
WildWilli
User
Beiträge: 3
Registriert: Samstag 4. Februar 2017, 00:56

mein Problem ist ja schon der Fenster aufbau :roll:
Der Zustand ist nicht Zeitkritisch! Die GPIOS können ruhig nur alle 3 min Aktualisiert werden.

Das Hauptprogramm wertet Schwimmerschalter aus und gibt bei Fehler nach 5 min Alarm per Mail und SMS.

Die GUI soll nur am Display des Raspberry dem Hausmeister zeigen wo der Fehler liegt
Benutzeravatar
Goswin
User
Beiträge: 363
Registriert: Freitag 8. Dezember 2006, 11:47
Wohnort: Ulm-Böfingen
Kontaktdaten:

BlackJack hat geschrieben:@WildWilli: Der Wunsch/Ansatz ist schon falsch. Wenn Du eine GUI programmierst, dann ist *die* das Hauptprogramm. Die GUI-Hauptschleife bestimmt den Programmablauf.
@BlackJack:
Wie man es macht, um ein nicht interaktives Fenster aufzubauen (also keine GUI, nur eine grafische Anzeige), diese Frage interessiert auch mich. Hat Python gar kein Tool für so etwas? Wenn man gar mehrere solche grafische Anzeigen gleichzeitig haben möchte, ist es programmiertechnisch einfach ungesund, die Kontrolle nicht beim Hauptprogramm zu belassen.
WildWilli
User
Beiträge: 3
Registriert: Samstag 4. Februar 2017, 00:56

Mit Tkinter geht das.
Ein "Hello World" habe ich damit auch schon hin bekommen. Aber leider nicht das was ich brauche.

Hier eine sehr gute Seite für Tkinter
http://www.python-kurs.eu/python_tkinter.php

!!! je nachdem welche Python Version man hat muss Tkinter beim Import groß oder klein geschrieben werden !!!
BlackJack

@Goswin: Warum ist das ”ungesund”? So ziemlich jedes GUI-Rahmenwerk funktioniert so und man kann die alle auch für Anzeigen benutzen. Werden sie ja auch. Letztlich funktionieren die Systeme auch so auf denen die GUI-Rahmenwerke aufsetzen, also Windows und X. Jedes Rahmenwerk das auf solchen Systemen dem Programmierer etwas anderes suggeriert, versteckt diesen Umstand nur vor dem Programmierer.
__deets__
User
Beiträge: 14494
Registriert: Mittwoch 14. Oktober 2015, 14:29

@Goswin: wo auch immer du so etwas herhaben willst - stimmt nicht. Grafische Ausgaben setzen ein viel hoeheres Mass an Involvierung mit dem System voraus, als eine simple Konsolen-Applikation die ein paar Daten durchroedelt. Auch wenn *DU* keine Interaktion willst - das System will eine Ereignisschleife bedient haben. Siehe spinning beachballs auf dem Mac, oder irgendwelche "das Programm reagiert nicht mehr"-Meldungen unter Windows. Insofern kommst du da nicht herum.
Benutzeravatar
Goswin
User
Beiträge: 363
Registriert: Freitag 8. Dezember 2006, 11:47
Wohnort: Ulm-Böfingen
Kontaktdaten:

@BlackJack & _deets_:
Ich weiß nicht, ob ihr mich richtig verstanden habt.
(1)
Mein Hauptmodul macht Berechnungen, die viel Zeit in Anspruch nehmen. Aus diesem Grund ist es wichtig sich laufend über dessen Fortschritt zu informieren und Zwischenergebnisse auszuwerten. Das geht natürlich auch schriftlich über das Terminal, oder durch die Ausgabe verschiedener Dateien, die man einsehen kann. Aber in einigen Fällen ist dieser Fortschritt leichter auszuwerten, wenn er grafisch dargestellt wird, und genau das möchte ich manchmal machen.
(2)
Das Hauptprogramm ist eindeutig die Hauptsache, und kann auch ohne grafische Darstellung durchlaufen und vernünftige Ergebnisse liefern. Die grafische Darstellung ist ohne das Hauptprogramm absolut sinnlos, sie soll ja nur berichten, was das Hauptprogramm gerade macht. Deshalb halte ich es (intuitiv) für "gesund" wenn das Hauptprogramm die grafische Darstellung von Zeit zu Zeit aufruft und nicht umgekehrt. Außerdem werden manchmal (je nach Verlauf) verschiedene grafische Darstellungen angezeigt.
(3)
Natürlich kann ich nur ein Rahmenmodul als Hauprogramm laufen lassen, und die sowohl die Berechnungen als auch die grafischen Darstellungen werden von diesem Rahmenmodul aus aufgerufen. Aber das verschiebt ja nur die obige Problematik: Wie mache ich es, dass Tkinter in einem parallelen Strang läuft, der reagiert, wenn er vom Rahmenmodul hin und wieder aufgerufen wird?

Meine bisher beste Lösung (ohne tkinter) für mein Anliegen ist nicht besonders elegant und nicht besonders effizient, und besteht darin, dass das Hauptmodul eine svg-Datei erstellt und diese von Zeit zu Zeit aktualisiert. Die aktuelle Version dieser Datei kann mir ich dann über Firefox nach Bedarf ansehen.
Benutzeravatar
Cronut
User
Beiträge: 34
Registriert: Sonntag 5. Februar 2017, 09:50
Wohnort: HRO, GER

Kurze Frage:
Was wäre für dich denn das angenehmste? Ein ganz kleinen simplen Webserver, der eine Seite aktualisiert? Eine Anzeigen auf einem Bildschirm, der an den PI angeschlossen ist? Die Anzeige der Zwischenergebnisse in einer GUI auf einem entfernen Rechner? Oder einfach nur eine kurze-aufploppende Nachricht? Eine PDF- oder Bild-datei mit allg. Informationen oder Details?

Du müsstest in deinem Hauptprogramm irgendeine Art von API anbieten, über die man sich beim Hauptprogramm registrieren kann um über Aktualisierungen informiert zu werden (oder diese halt explizit nachfragen).

Du könntest die Zwischenergebnisse bzw. Fortschritte auch in eine XML-Datei übertragen und diese mit CSS verbinden um eine "hübsche" Darstellung zu erreichen. Eventuell in Verbindung mit Anmeldung eines anderen Programms, dass eine Socketverbindung zu deinem Hauptprogramm aufbaut und über RPC kommuniziert.

Ich denke da gibt es viele Möglichkeiten. Du müsstest dir einen Weg aussuchen.
“Clean code always looks like it was written by someone who cares.” (Michael Feathers)
Check out: https://awesome-python.com/
BlackJack

@Goswin: Ich denke schon das wir verstanden haben und auch hatten was Du gerne möchtest. Das Problem ist halt das grafische Systeme das so schlicht nicht vorsehen. Die haben eine Hauptschleife und die muss auch laufen, sonst friert die GUI ein und das System fragt den Benutzer ob er die Anwendung killen möchte, weil sie nicht mehr reagiert.

Lang laufende Berechnungen kann man in einem eigenen Thread laufen lassen und ab und zu Daten in eine Queue schreiben lassen. Die kann man dann regelmässig von der GUI-Seite aus abfragen und eventuell vorhandene Daten/Zwischenergebnisse visualisieren. Oder man informiert den GUI-Thread über ein benutzerdefiniertes Ereignis das Daten in der Queue vorliegen. Die Daten selber kann man bei Tkinter leider nicht mit dem Ereignis übertragen. In Qt geht das beispielsweise mit dem Signal/Slot-Konzept. In wxPython gibt es `wx.CallAfter()` um aus anderen Threads Aufrufe von der GUI-Hauptschleife aus anzustossen.
Antworten