计时器是否正在从另一个线程启动?

问题描述 投票:0回答:1

QThread文档提出了两种使代码在单独的线程中运行的方法。如果我将QThread子类化并重新实现run(),则得到

QBasicTimer::start: Timers cannot be started from another thread  

-

#include <QWidget>
#include <QThread>
#include <QBasicTimer>

class Worker : public QThread
{
    Q_OBJECT
public:
    Worker() {}
protected:
    void run() {
        QBasicTimer timer;
        timer.start(1000, this);
    }
};

class MainWidget : public QWidget
{
public:
    MainWidget()
    {
        auto worker = new Worker;
        worker->start();
    }
};

1)计时器是否正在从另一个线程启动?2)为什么用QTimer代替QBasicTimer时,我没有收到警告?3)为什么在使用moveToThread时没有收到该警告?

class Worker : public QObject
{
    Q_OBJECT
public:
    Worker() {}
public slots:
    void run() {
        QBasicTimer timer;
        timer.start(1000, this);
    }
};

class MainWidget : public QWidget
{
    Q_OBJECT
    QThread thread;
public:
    MainWidget()
    {
        auto worker = new Worker;
        worker->moveToThread(&thread);
        connect(this, &MainWidget::start, worker, &Worker::run);
        thread.start();
        emit start();
    }
    ~MainWidget(){thread.quit(); thread.wait();}
signals:
    void start();
};
c++ multithreading qt qthread qtimer
1个回答
0
投票

关于第一个(非moveToThread)示例...

快速浏览QBasicTimer::start的Qt源显示以下内容...

QBasicTimer::start

因此,它希望其第二个参数void QBasicTimer::start(int msec, QObject *obj) { QAbstractEventDispatcher *eventDispatcher = QAbstractEventDispatcher::instance(); // ... if (Q_UNLIKELY(obj && obj->thread() != eventDispatcher->thread())) { qWarning("QBasicTimer::start: Timers cannot be started from another thread"); return; } 具有与当前线程相同的线程亲和力。

但是,在您的obj实现中,您有...

Worker::run

在这种情况下,当前线程是由timer.start(1000, this); 实例创建的新线程,但是QThread指代主GUI线程上由this创建的QWorker实例。因此,警告。

© www.soinside.com 2019 - 2024. All rights reserved.