QObject :: startTimer: timers can only be used with threads started with QThread

I am trying to start a timer in a workflow event loop, but I am getting this error: QObject::startTimer: Timers can only be used with threads started with QThread

What is wrong with this?

#include <QObject>
#include <QThread>
#include <QTimer>

class A : public QObject
{
    Q_OBJECT
public:
    A();

private:
    QThread m_workerThread;
    QTimer m_myTimer;

};

A::A()
{
    this->moveToThread(&m_workerThread);
    m_myTimer.moveToThread(&m_workerThread);
    m_workerThread.start();
    m_myTimer.start(1000);
}
0
source share
3 answers

I think I figured it out, I tried to start the timer from the GUI thread, after I moved it to the workflow, this way it works:

class A : public QObject
{
    Q_OBJECT
public:
    A();

private:
    QThread m_workerThread;
    QTimer m_myTimer;

public slots:
    void sl_startTimer();
};

A::A()
{
    this->moveToThread(&m_workerThread);
    m_myTimer.moveToThread(&m_workerThread);
    m_workerThread.start();
    QMetaObject::invokeMethod(this, "sl_startTimer", Qt::QueuedConnection);
}

void A::sl_startTimer()
{
    m_myTimer.start(1000);
}
+1
source

Initialize your timer anywhere, but start it right away when the thread is running (attach it to QThread :: started ):

class A : public QObject
{
    Q_OBJECT
public:
    A();

private slots:
    void started();
    void timeout();

private:
    QThread m_workerThread;
    QTimer m_myTimer;
};

A::A()
{
    moveToThread(&m_workerThread);

    connect(&m_workerThread, SIGNAL(started()), this, SLOT(started()));
    connect(&m_myTimer, SIGNAL(timeout()), this, SLOT(timeout()));

    m_myTimer.setInterval(1000);
    m_myTimer.moveToThread(&m_workerThread);

    m_workerThread.start();
}

void A::started()
{
    timer.start();
}

void A::timeout()
{
    // timer handler
}
+1
source

This approach seems a little dangerous to me. By moving QObjectto QThread, you make the stream responsible for the events of the object (signals, slots, messages, etc.). However, when an object is deleted, the stream will be deleted to the object itself, which may lead to unexpected behavior.

the recommended approach is to instantiate the stream and the object separately.

0
source

Source: https://habr.com/ru/post/1588875/


All Articles