I have a QTimer to do stuff at intervals. Sometimes, this stuff raises an exception. When that happens, I must stop the QTimer without destroying it, so I can restart it later on. However, when I attempt to stop it from within its timeout event, it doesn't stop immediately, but rather keeps ticking multiple times for a short period before stopping, and produces a Timers cannot be stopped from another thread
error.
What is the proper way to make the timer stop itself immediately, without errors?
Here's my demo code:
import sys
from PyQt5.QtCore import *
from PyQt5.QtWidgets import *
class MyWorker(QObject):
def __init__(self):
super().__init__()
self.timer = QTimer(self)
self.timer.timeout.connect(self.tick)
def begin(self):
self.timer.start(1)
def tick(self):
try:
print("error raised")
raise Exception()
except:
print("error caught, stopping")
self.timer.stop()
class MainWindow(QMainWindow):
startSignal = pyqtSignal()
def __init__(self):
super().__init__()
self.myThread = QThread()
self.myWorker = MyWorker()
self.myWorker.moveToThread(self.myThread)
self.startSignal.connect(self.myWorker.begin)
self.myThread.start()
self.startSignal.emit()
if __name__ == '__main__':
app = QApplication(sys.argv)
window = MainWindow()
sys.exit(app.exec())
and the output:
error raised
error caught, stopping
error raised
error caught, stopping
error raised
error caught, stopping
error raised
error caught, stopping
error raised
error caught, stopping
error raised
error caught, stopping
error raised
error caught, stopping
error raised
error caught, stopping
error raised
error caught, stopping
error raised
error caught, stopping
error raised
error caught, stopping
error raised
error caught, stopping
error raised
error caught, stopping
error raised
error caught, stopping
error raised
error caught, stopping
error raised
error caught, stopping
error raised
error caught, stopping
QObject::killTimer: Timers cannot be stopped from another thread