@twessels: "timer1" ist ein
lokaler Name in "Chatty.__init__()". Nach dem Ende der Ausführung von "__init__()" wird der Name "timer1" gelöscht, weil der Namensraum der Methode "__init__()" natürlich nicht länger existiert. In dem gezeigten Programm ist dieser Name allerdings die einzige Referenz auf das daran gebundene "QTimer"-Objekt. Die automatische Speicherverwaltung von Python [1] löscht folglich das "QTimer"-Objekt. Somit kann nach dem Ablauf der Sekunde auch kein "timeout()" ausgelöst werden, das "QTimer"-Objekt existiert ja schon nicht mehr.
Die Lösung ist, irgendwie eine über das Ende von "__init__()" hinausgehende Referenz auf dieses Objekt zu halten. Dazu gibt es zwei Wege. Der erste ist, "timer1" an das Exemplar zu binden:
Code: Alles auswählen
self.timer1 = QTimer()
self.timer1.timeout.connect(self.chatter)
self.timer1.start(1000)
Die andere Lösung, welche ich in diesem Falle empfehlen würde, ist Qt dieses Objekt zur Verwaltung zu überlassen, indem man ein gültiges Vater-Objekt setzt:
Code: Alles auswählen
timer1 = QTimer(self)
timer1.timeout.connect(self.chatter)
timer1.start(1000)
Damit übernimmt Qt die Speicherverwaltung für dieses Objekt, was in diesem Fall empfehlenswert ist, da zumindest im gezeigten Beispieltext von Python aus nicht mehr auf das Objekt zugegriffen wird.
Im Allgemeinen ist es immer empfehlenswert, das Vater-Objekt für Qt-Objekte korrekt zu setzen. Das gilt vor allem und insbesondere für Steuerelemente, sprich Exemplare von "QWidget" oder davon abgeleiteten Klassen.
In C++ funktioniert der Quelltext übrigens nur deswegen, weil C++ keine Speicherverwaltung hat und Objekte somit "ewig" leben, wenn sie nicht explizit gelöscht werden. Kurz gesagt, der C++-Quelltext hat ein Speicherleck, und ist dementsprechend auch nicht sonderlich gut.
[1] Genauer gesagt geht es hier nur um die spezielle Implementierung der Speicherverwaltung in CPython. Alternative Python-Implementierungen wie Jython, IronPython und PyPy können sich hier in der Tat anders verhalten. Insgesamt ist das Verhalten für nicht mehr referenzierte Objekte in Python per definitionem undefiniert.