Turtles Are Cute
Turtles Are Cute

Reputation: 3426

QT Timers not calling function

I'm using PyQt with Python3.

My QTimers are not calling the function they're told to connect to. isActive() is returning True, and interval() is working correctly. The code below (works standalone) demonstrates the problem: The thread is successfully started, but the timer_func() function is never called. Most of the code is boilerplate PyQT. As far as I can tell, I'm using this in accordance with the docs. It's in a thread with an event loop. Any ideas?

import sys
from PyQt5 import QtCore, QtWidgets

class Thread(QtCore.QThread):
    def __init__(self):
        QtCore.QThread.__init__(self)

    def run(self):
        thread_func()


def thread_func():
    print("Thread works")
    timer = QtCore.QTimer()
    timer.timeout.connect(timer_func)
    timer.start(1000)
    print(timer.remainingTime())
    print(timer.isActive())

def timer_func():
    print("Timer works")

app = QtWidgets.QApplication(sys.argv)
thread_instance = Thread()
thread_instance.start()
thread_instance.exec_()
sys.exit(app.exec_())

Upvotes: 1

Views: 7753

Answers (1)

mata
mata

Reputation: 69012

You're calling thread_func from withn the run method of your thread, that means the timer your create in that function lives in that thread's event loop. To start a threads event loop, you must call it's exec_() method from within it's run method, not from the main thrad. In your example here, app.exec_() never gets executed. To make it work, just move the exec_ call into the thread's run.

An additional problem is that your timer gets destroyed when thread_func finishes. To keep it alive, you must keep a reference somewhere.

import sys
from PyQt5 import QtCore, QtWidgets

class Thread(QtCore.QThread):
    def __init__(self):
        QtCore.QThread.__init__(self)

    def run(self):
        thread_func()
        self.exec_()

timers = []

def thread_func():
    print("Thread works")
    timer = QtCore.QTimer()
    timer.timeout.connect(timer_func)
    timer.start(1000)
    print(timer.remainingTime())
    print(timer.isActive())
    timers.append(timer)

def timer_func():
    print("Timer works")

app = QtWidgets.QApplication(sys.argv)
thread_instance = Thread()
thread_instance.start()
sys.exit(app.exec_())

Upvotes: 7

Related Questions