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();
};
关于第一个(非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
实例。因此,警告。