A QTimer
нужен работающий цикл обработки событий. По умолчанию QThread.run()
запускает локальный цикл обработки событий для потока, но если вы полностью переопределите его так, как вы это сделали, этого не произойдет, поэтому события таймера никогда не будут обрабатываться.
В общем, когда вам нужен локальный цикл обработки событий, вы должны создать рабочий объект для выполнения всей обработки, а затем использовать moveToThread , чтобы поместить его в отдельный поток. Если нет, то вполне нормально переопределить QThread.run()
.
Демонстрация ниже показывает, как это сделать. Обратите внимание, что очень важно создать таймер после запуска потока , иначе он будет создан в неправильном потоке, а его события таймера не будут обработаны циклом обработки потока. Также важно, чтобы вся связь между рабочим потоком и основным потоком осуществлялась с помощью сигналов, чтобы обеспечить безопасность потока. Никогда не пытайтесь напрямую выполнять операции с графическим интерфейсом вне основного потока, так как Qt вообще не поддерживает это. В целях демонстрации второй таймер в основном потоке используется для остановки всей обработки после фиксированного интервала. Если бы был GUI, пользовательское вмешательство через кнопку могло бы достичь того же.
Демо
import sys
from PyQt5.QtCore import *
from PyQt5.QtWidgets import *
class ModbusComWorker(QObject):
finished = pyqtSignal()
def start(self):
self._timer = QTimer(self)
self._timer.timeout.connect(self.process)
self._timer.start(2000)
def stop(self):
self._timer.stop()
self.finished.emit()
def process(self):
print('processing (thread: %r)' % QThread.currentThread())
QThread.sleep(3)
if __name__ == "__main__":
app = QCoreApplication.instance()
if app is None:
app = QApplication(sys.argv)
thread = QThread()
worker = ModbusComWorker()
worker.moveToThread(thread)
def finish():
print('shutting down...')
thread.quit()
thread.wait()
app.quit()
print('stopped')
worker.finished.connect(finish)
thread.started.connect(worker.start)
thread.start()
timer = QTimer()
timer.setSingleShot(True)
timer.timeout.connect(worker.stop)
timer.start(15000)
print('starting (thread: %r)' % QThread.currentThread())
sys.exit(app.exec_())
выход
starting (thread: <PyQt5.QtCore.QThread object at 0x7f980d096b98>)
processing (thread: <PyQt5.QtCore.QThread object at 0x7f980d0968a0>)
processing (thread: <PyQt5.QtCore.QThread object at 0x7f980d0968a0>)
processing (thread: <PyQt5.QtCore.QThread object at 0x7f980d0968a0>)
processing (thread: <PyQt5.QtCore.QThread object at 0x7f980d0968a0>)
processing (thread: <PyQt5.QtCore.QThread object at 0x7f980d0968a0>)
shutting down...
stopped