Timer in child theme in PySide

First, I am very new to Python and Pyside. To improve self-improvement a bit, I'm trying to get QTimer to execute every second on a child thread of my PySide program (for now, I just want it to print β€œhello!” To the terminal every second without freezing the main window).

I tried to convert the example I found on the Qt Wiki from C ++ to Python / PySide, but since I don't really know C ++ I'll assume I converted it incorrectly and why it doesn't work as expected.

Currently, the doWork () function only works once, and then never again. What am I doing wrong? Is there a better way to execute a function every second in PySide without freezing the main window?

Here's the code (I've removed the main window code to increase clarity):

from PySide import QtGui
from PySide import QtCore
from client_gui import Ui_MainWindow

statsThread = QtCore.QThread()

class MainWindow(QtGui.QMainWindow, Ui_MainWindow):
    def __init__(self, parent=None):
        super(MainWindow, self).__init__(parent)
        #setup GUI
        self.setupUi(self)
        #start thread to update GUI
        self.statsThread = updateStatsThread()
        self.statsThread.start(QtCore.QThread.TimeCriticalPriority)

class updateGuiWithStats(QtCore.QObject):
    def Worker(self):
        timer = QtCore.QTimer()
        timer.timeout.connect(self.doWork())
        timer.start(1000)

    def doWork(self):
        print "hi!"

class updateStatsThread (QtCore.QThread):
    def run(self):
        updater = updateGuiWithStats()
        updater.Worker()
        self.exec_()

if __name__ == '__main__':
    app = QtGui.QApplication(sys.argv)
    frame = MainWindow()
    frame.show()
    sys.exit(app.exec_())

      

+3


source to share


2 answers


@Masci already pointed out the fix you need for yours timer.timeout.connect

, but I see more problems than just that.

No need to create a global QThread that is never used:

statsThread = QtCore.QThread()

      

Your QTimer is garbage collected right away because it was created without a parent and you are not saving it in your class. This is why even after you fix the timer connection it still won't work ... Try:



class UpdateGuiWithStats(QtCore.QObject):

    def startWorker(self):
        self.timer = QtCore.QTimer()
        self.timer.timeout.connect(self.doWork)
        self.timer.start(1000)

      

Also, use UpperCase for the first letter of the classes and camelCase for the methods. You are doing a mixture of both.

A couple of notes based on this link you provided, your example and other comments here ... You can only use QTimer as a solution if yours is doWork()

very light and won't block your main event loop with a bunch of data crunching, sleeping, etc. .d. If so, doWork()

you will need to move to QThread, as your example does. But at this point there is no need to use the event loop and QTimer in a separate class that calls its own work. All this can be combined into one class, for example:

class UpdateStatsThread(QtCore.QThread):

    def __init__(self, parent=None):
        super(UpdateStatsThread, self).__init__(parent)
        self._running = False

    def run(self):
        self._running = True
        while self._running:
            self.doWork()
            self.msleep(1000)

    def stop(self, wait=False):
        self._running = False
        if wait:
            self.wait()

    def doWork(self):
        print "hi!"

      

+4


source


in the classroom updateGuiWithStats

, Worker

:

timer.timeout.connect(self.doWork())

      

it should be



timer.timeout.connect(self.doWork)

      

You are connecting the timeout signal to None

(method return value doWork()

) and I think this is why it is only executed once: doWork

called during connection and nomore. When making connections, remember to include the function name (in Pythonics words, the callable), not the function call.

By the way, even if the above is a solution to your problem, you should avoid using streams as QTimer already does on its own. In the docs you linked , the first answer to the question is when should I not use streams? question: Timers.

+1


source







All Articles