I need to calculate a number in a thread and then to process the data, but the timer in a thread not working.
from PyQt5.QtWidgets import *
from PyQt5.QtGui import *
from PyQt5.QtCore import Qt, QObject, QThread, pyqtSlot, QTimer
import sys, time
class Worker(QObject):
def __init__(self):
super().__init__()
self.i = 0
self.startTimer(100)
def timerEvent(self, QTimerEvent):
self.i += 2
@pyqtSlot()
def run(self):
while True:
print(self.i)
time.sleep(1)
class Demo(QWidget):
def __init__(self):
super().__init__()
self.worker = Worker()
self.thread = QThread()
self.worker.moveToThread(self.thread)
self.thread.started.connect(self.worker.run)
self.thread.start()
app = QApplication(sys.argv)
demo = Demo()
demo.show()
app.exec()
The teminal show 0 always, can anyone help me.
The signals and events need an event loop to work. When you use a QThread
you create that event loop but when using time.sleep()
you are blocking it preventing timerEvent()
method from being invoked. So the solution is to replace time.sleep()
with another option (QEventLoop + QTimer) that does not block it.
from PyQt5 import QtCore, QtWidgets
class Worker(QtCore.QObject):
def __init__(self):
super().__init__()
self.i = 0
self.m_id = self.startTimer(100)
def timerEvent(self, event):
if self.m_id == event.timerId():
self.i += 2
super().timerEvent(event)
@QtCore.pyqtSlot()
def run(self):
while True:
print(self.i)
loop = QtCore.QEventLoop()
QtCore.QTimer.singleShot(1000, loop.quit)
loop.exec()
class Demo(QtWidgets.QWidget):
def __init__(self, parent=None):
super().__init__(parent)
thread = QtCore.QThread(self)
self.worker = Worker()
self.worker.moveToThread(thread)
thread.started.connect(self.worker.run)
thread.start()
if __name__ == "__main__":
import sys
app = QtWidgets.QApplication(sys.argv)
demo = Demo()
demo.show()
sys.exit(app.exec())