首页 > 解决方案 > QTimer 在 QThread 中运行

问题描述

我需要一个带有计时器的类,它每 100 毫秒执行一次任务,这个类需要在线程中运行,所以我想将 qtimer 与 qthread 结合使用。

我创建了以下代码:

class Worker : public QObject
{
    Q_OBJECT
    public:
    void setEnabled(bool enable);
    
    public slots:
    void initialize();
    
    private:
    void doWork();
    
    QTimer *m_timer;
}

void Worker::initialize()
{
    m_timer = new QTimer(this);
    connect(m_timer, &QTimer::timeout, this, &Worker::doWork, Qt::DirectConnection);
    m_timer->start(100);
}

void Worker::setEnabled(bool enable)
{
    if(enable)
        m_timer->start(100);
    else
        m_timer->stop();
}

int main(int argc, char *argv[])
{
    QCoreApplication app(argc,argv);

    QThread *thread = new QThread;
    Worker *worker = new Worker;
    
    QObject::connect(thread, &QThread::started, worker, &Worker::initialize);
    
    worker->moveToThread(thread);
    thread->start();
    
    app.exec();

    delete worker;
    delete thread;
}

使用以下命令,我可以启用/禁用时间

工人->setEnabled(false); 工人->setEnabled(true);

我已经测试过,它工作正常,但我想知道这是否是正确的方法?

谢谢您的帮助

标签: c++qtqthreadqtimer

解决方案


不,这并不完全正确。

Worker::setEnabled(bool enable)也应该是一个插槽,因为它QTimer::start()直接调用插槽。然后直接从主线程调用Worker::setEnabled会导致未定义的行为。您必须使用信号槽连接setEnabled从主线程安全调用。

您还应该Worker::m_timer在构造函数中进行初始化,而不是将其推迟到,因此如果调用的时间早于预期initialize(),您就不会遇到悬空指针。会用它来感动所有的孩子,所以这是完全理智的行为。Worker::setEnabledmoveToThreadWorker


推荐阅读