QTimer, threads, and non-gui events

Heads up! You've already completed this tutorial.

Saar_Drimer | 2021-06-27 15:54:39 UTC | #1

Firstly, the book has been a really good reference and learning tool... thanks!

I'm a bit stuck trying to implement something. I've created the following test script:

python
from PySide2 import QtCore, QtWidgets

class MainWindow(QtWidgets.QMainWindow):
    def __init__(self, parent=None):

        super().__init__()
        self._setup_timer()

        layout = QtWidgets.QVBoxLayout()
        self.l = QtWidgets.QLabel("Tick tester")
        b = QtWidgets.QPushButton("START")
        b.pressed.connect(self._do_thing)
        layout.addWidget(self.l)
        layout.addWidget(b)
        w = QtWidgets.QWidget()
        w.setLayout(layout)
        self.setCentralWidget(w)
        self.show()

    def _setup_timer(self):
        self._timer = QtCore.QTimer()
        self._timer.timeout.connect(self._timer_tick)

    def _do_thing(self):
        self._tick_count = 0
        self._timer.start(1000)
        for n in range(0, 3):
            print(f"n={n}")
            for m in range(0, 5):
                print(f"m={m}")
        # stop timer
        print("do one more thing")

    def _timer_tick(self):
        print(f"Timer tick: {self._tick_count}")
        print("I'm doing something every second!")
        self._tick_count += 1


app = QtWidgets.QApplication([])
window = MainWindow()
app.exec_()

And as you'd expect I get the following output:

python
n=0
m=0
m=1
m=2
m=3
m=4
n=1
m=0
m=1
m=2
m=3
m=4
n=2
m=0
m=1
m=2
m=3
m=4
do one more thing
Timer tick: 0
I'm doing something every second!
Timer tick: 1
I'm doing something every second!
Timer tick: 2
I'm doing something every second!
Timer tick: 3
I'm doing something every second!

But what I'm actually after is 'waiting' for the ticks in do_thing's m for loop such that the output looks something more like this:

python
n=0
m=0
Timer tick: 0
I'm doing something every second!
m=1
Timer tick: 1
I'm doing something every second!
m=2
Timer tick: 2
I'm doing something every second!
...
do one more thing

And, that do one more thing happens after the nested for loops are done with. (I'm not including the _tick_count test because that's part of the problem ;) )

What I'm missing is how to 'connect' what's happening with the 'ticks' with the main event loop such that it knows when to proceed / wait .

I've read the excellent section in the book about threads:

https://www.mfitzp.com/tutorials/multithreading-pyqt-applications-qthreadpool/

together with other resources for how to possible achieve what I want. It's clear that the print in _timer_tick will need to be replaced with a worker thread.

Should I use worker signals? Am I missing something trivial (quite possible!)

What I'd like to understand better is what is the simplest and most robust way to do it. If anyone has good pointers, I'd appreciate it.

Thanks!


Over 10,000 developers have bought Create GUI Applications with Python & Qt!
Create GUI Applications with Python & Qt5
Take a look

Downloadable ebook (PDF, ePub) & Complete Source code

Also available from Leanpub and Amazon Paperback

[[ discount.discount_pc ]]% OFF for the next [[ discount.duration ]] [[discount.description ]] with the code [[ discount.coupon_code ]]

Purchasing Power Parity

Developers in [[ country ]] get [[ discount.discount_pc ]]% OFF on all books & courses with code [[ discount.coupon_code ]]
Well done, you've finished this tutorial! Mark As Complete
[[ user.completed.length ]] completed [[ user.streak+1 ]] day streak

QTimer, threads, and non-gui events was written by Martin Fitzpatrick .

Martin Fitzpatrick has been developing Python/Qt apps for 8 years. Building desktop applications to make data-analysis tools more user-friendly, Python was the obvious choice. Starting with Tk, later moving to wxWidgets and finally adopting PyQt.