I want to run a python while-loop for x amount of time (2 seconds) and then stop:
from PyQt6 import QtCore
def loop():
stop = False
def stop_loop():
nonlocal stop
stop = True
print('STOPPING LOOP')
timer = QtCore.QTimer()
timer.setSingleShot(True)
timer.setInterval(2000)
timer.timeout.connect(stop_loop)
timer.start()
counter = 0
while 1:
counter += 1
print(counter)
if stop:
break
app = QtCore.QCoreApplication([])
loop()
app.exec_()
But the loop keeps running infinitely and never stops.
The QTimer
posts an event to the event-queue when it times-out, but your while-loop blocks all processing of events, so the timer-event never gets processed. To get your example to work, you would need to periodically force processing of any pending events:
def loop():
...
while 1:
counter += 1
print(counter)
# clear event-queue
app.processEvents()
if stop:
break
# do some more work...
QtCore.QThread.msleep(100)
Whilst this method works for some simple cases, it's not usually very scalable, so the preferred approach is to move the blocking task into a separate worker thread, like this:
from PyQt6 import QtCore
class Thread(QtCore.QThread):
def stop(self):
self._stopped = True
print('STOPPING LOOP')
def run(self):
self._stopped = False
counter = 0
while not self._stopped:
counter += 1
print(counter)
# do some more work...
self.msleep(100)
app = QtCore.QCoreApplication(['Test'])
thread = Thread()
thread.finished.connect(app.quit)
QtCore.QTimer.singleShot(2000, thread.stop)
thread.start()
app.exec()