Verwendung von QTimer

Python und das Qt-Toolkit, erstellen von GUIs mittels des Qt-Designers.
Antworten
helloBavaria
User
Beiträge: 6
Registriert: Donnerstag 17. Februar 2022, 11:32

Hallo,
ich versuche mich gerade mit QWidgets und QTimern.
Speziell verwende ich "QTimer.singleshot(5000, funktion)", womit ich an gewünschter Stelle nach 5 Sekunden "funktion" aufrufen will.

Ich frage mich gerade, wann genau im Python-Prozess die "funktion" dann tatsächlich ausgeführt wird? Ich habe ja keinen anderen thread und es ist doch auch gut möglich dass Python mit anderen Methoden etc. beschäftigt ist.

Kann hier jemand "Licht ins Dunkle" bringen? :)
__deets__
User
Beiträge: 14494
Registriert: Mittwoch 14. Oktober 2015, 14:29

Eine GUI hat einen mainloop (bei Qt mit App.exec betreten), und der verarbeitet Ereignisse. Und genau das ist ein Timer. Nur statt einem Tastendruck oder einer Mausaktion ist es eben ein Timer-Ereignis. Womit im Umkehrschluss natürlich folgt: wenn der mainloop gerade nicht vor sich hin loopt, weil das Programm stattdessen längere Berechnungen durchführt, dann kommen diese Ereignisse verspätet an. Und genau das passiert, wenn Windows zb das berüchtigte “Anwendung reagiert nicht” anmerkt. Weshalb es ein Fehler ist, in GUIs längere Berechnungen zu machen. Die müssen wahlweise in kleine Happen zerteilt werden (die dann zb per Timer abgearbeitet werden), oder explizit in einen Hintergrund-Thread verlagert werden. Aber Achtung: letzteres erzeugt seinen eigenen Sack Probleme, wenn diese Arbeit wiederum in der GUI reflektiert werden soll, zb per Progressbar.
helloBavaria
User
Beiträge: 6
Registriert: Donnerstag 17. Februar 2022, 11:32

Danke für die schnelle Antwort.
Im Umkehrschluss heißt das, nach 5 Sekunden wird geschaut ob gerade Zeit ist und ggf. die Funktion ausgeführt. Wenn Python noch anderweitig beschäftigt ist, dann wird die Funktion halt in 5 Sekunden + x, also etwas verspätet, ausgeführt, oder?
Benutzeravatar
sparrow
User
Beiträge: 4164
Registriert: Freitag 17. April 2009, 10:28

Das hat mit Python nichts zu tun. Jedes mir bekannte GUI-Rahmenwerk hat den von __deets__ beschriebenen "main loop". Eine Schleife die endlos läuft und die GUI zeichnet und Ergeinisse abarbeitet. Der kommt irgendwann vorbei und führt deinen Timer aus. Deshalb werden es nie genau 5 Sekunden sein. Aber in einer vernünftig programmierten Oberfläche, in der der Mainloop nicht blockiert, wird das Ereignis zeitnah an den 5 Sekunden ausgeführt (also wahrscheinlich zu einem Zeitpunkt, der für dich "sofort" ist).
So ein Ereignis ist auch das Klicken auf einen Button. Das wird ja auch sofort ausgeführt und nicht "wenn mal Zeit ist". Es sei denn, der mainloop läuft eben nicht -> dann kommt das von __deets__ beschriebene "Die Anwendung reagiert nicht".
__deets__
User
Beiträge: 14494
Registriert: Mittwoch 14. Oktober 2015, 14:29

Das ganze geht tiefer. Der mainloop ist eigentlich im OS verankert, und das bietet ebenfalls Timer. Das OS ist in der Lage, Prozesse wirklich schlafen zu legen (und macht das permanent fur Multitasking), und führt interne Tabellen, wann ein Prozess wieder aufzuwecken ist. Was im Grunde aus drei Gründen erfolgt: IO, Timer, oder er wurde preemptet, also schlafen gelegt, obwohl er aktiv gerechnet hat, und soll wieder drankommen.
Antworten