Skip to content Skip to sidebar Skip to footer

Running A Heavy Qtimer Task As A Qthread

I have a heavy task that constantly runs every 500ms. It consists of updating GUI elements and I need access to its variables at all times. The task performed: A list that is dynam

Solution 1:

With QThread it is difficult to implement that logic (you would have to use QThread.msleep, mutex, etc). Instead a simple solution is to create a new thread every T seconds and that will be implemented using threading.Thread + QTimer (can also be implemented with QThreadPool + QRunnable + QTimer):

import random
import sys
import threading
import time


from PySide2 import QtCore, QtWidgets
import shiboken2


class Worker(QtCore.QObject):
    output = QtCore.Signal(object)


def long_running_function(values, worker):
    for element in values:
        time.sleep(0.1)
        if shiboken2.isValid(worker):
            worker.output.emit(element)


class Widget(QtWidgets.QWidget):
    def __init__(self, parent=None):
        super().__init__(parent)

        self.label = QtWidgets.QLabel(alignment=QtCore.Qt.AlignCenter)
        self.button = QtWidgets.QPushButton("Start")

        lay = QtWidgets.QVBoxLayout(self)
        lay.addWidget(self.button)
        lay.addWidget(self.label)

        self.timer = QtCore.QTimer(interval=500)

        self.button.clicked.connect(self.handle_clicked)
        self.timer.timeout.connect(self.launch_task)

    def handle_clicked(self):
        if self.button.text() == "Start":
            self.timer.start()
            self.button.setText("Stop")
        elif self.button.text() == "Stop":
            self.timer.stop()
            self.button.setText("Start")

    def launch_task(self):
        values = random.sample(range(1, 50), 20)
        worker = Worker()
        worker.output.connect(self.label.setNum)
        threading.Thread(
            target=long_running_function,
            args=(values, worker),
            daemon=True,
        ).start()


if __name__ == "__main__":
    app = QtWidgets.QApplication(sys.argv)
    w = Widget()
    w.show()
    sys.exit(app.exec_())

Post a Comment for "Running A Heavy Qtimer Task As A Qthread"