I have a GUI project which uses PySide2 with Python 3.8, which performs some background tasks in a QThread
. Within that QThread
, I have QTimer
member object that has to periodically run a function passing it different data each time. I am not using QTimer.singleShot
static function because I need to stop/reset the timer if need be for some specific scenario.
Once the target function runs successfully, it invokes another function which is responsible for passing new data to the timer and run it again. The function is connected with timer.timeout.connect(lambda: function_name(data))
and before passing it new data I stop and disconnect the previous slot and stop the timer if the timer was active. On the second run of the timer when I pass it new data, the target function still runs with the old data somehow.
The following code is the issue reproduced in an isolated manner:
from PySide2.QtCore import QTimer
from PySide2 import QtWidgets
import time
import logging
logger = logging.getLogger(__name__)
logger.setLevel(logging.INFO)
FORMAT = "[%(asctime)s] %(funcName)s: %(message)s"
logging.basicConfig(format=FORMAT)
class QtTest(QtWidgets.QWidget):
def __init__(self):
super(QtTest, self).__init__()
logger.info("Class initialized")
self.timer = QTimer()
self.timer.setSingleShot(True)
self.timer.setInterval(1000)
self.timer.timeout.connect(lambda: self.target_func(0))
self.timer.start()
def target_func(self, data):
logger.info("Target function called with data: {}".format(data))
time.sleep(1.5)
if self.timer.isActive():
logger.info("Timer reset")
self.timer.stop()
self.timer.timeout.disconnect()
self.func_done(data)
def func_done(self, data):
logger.info("Tasks completed for data: {}".format(data))
if data == 0:
logger.info("Setting next timer with data 1")
#I have tried the following as well
#self.timer.timeout.disconnect()
#self.timer.stop()
self.timer.setInterval(1000)
self.timer.timeout.connect(lambda: self.target_func(1))
self.timer.start()
def init_app():
app = QtWidgets.QApplication([])
gui = QtTest()
gui.show()
app.exec_()
if __name__ == "__main__":
print("QT app running")
init_app()
test = QtTest()
This is the output of the test code:
QT app running
[2024-07-30 22:44:53,204] __init__: Class initialized
[2024-07-30 22:44:54,255] target_func: Target function called with data: 0
[2024-07-30 22:44:55,757] func_done: Tasks completed for data: 0
[2024-07-30 22:44:55,757] func_done: Setting next timer with data 1
[2024-07-30 22:44:56,808] target_func: Target function called with data: 0
[2024-07-30 22:44:58,309] func_done: Tasks completed for data: 0
[2024-07-30 22:44:58,309] func_done: Setting next timer with data 1
[2024-07-30 22:44:58,309] target_func: Target function called with data: 1
[2024-07-30 22:44:59,810] target_func: Timer reset
[2024-07-30 22:44:59,811] func_done: Tasks completed for data: 1
What I am expecting at
[2024-07-30 22:44:55,757] func_done: Setting next timer with data 1
[2024-07-30 22:44:56,808] target_func: Target function called with data: 0
is the following:
[2024-07-30 22:44:55,757] func_done: Setting next timer with data 1
[2024-07-30 22:44:56,808] target_func: Target function called with data: 1
soslearn is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.