QTimer在非QThread的环境下能正常工作。但在QThread环境下,需要做一些改动才能正常工作。
创建Qt的线程有两种方式:
1. 子例化QThread
可以在虚函数run中启动定时器,大致的代码如下:
//构造函数,继承QThread Thread::Thread(QObject *parent) : QThread(parent) { } void Thread::run() { QTimer* timer = new QTimer; //多线程环境中,此处设父指针为this,会导致创建线程失败,定时器可用 connect(timer, SIGNAL(timeout()), this, SLOT(display())); timer->start(1000); exec(); //开启事件循环 } //调用,启动线程 Thread* thread = new Thread; //此处设父指针为this,关闭应用程序时会发生崩溃 thread->start();
两处指针new的时候不能加this指针,run函数中必须加exec函数。
很不理解Qt为什么会这么干???
2. 继承QObject,使用moveToThread移入线程
大致的代码如下:
Calc::Calc(int start, int step) : m_cur(start) , m_step(step) { QThread* thread = new QThread; moveToThread(thread); thread->start(); QTimer* timer = new QTimer; //多线程环境中,此处设父指针为this,会导致创建线程失败,定时器可用 connect(timer, SIGNAL(timeout()), this, SLOT(display())); timer->start(1000); } Calc* c = new Calc(0, 1);
构造函数内两处指针new的时候,也不能加this
具体的代码如下:
#ifndef WIDGET_H #define WIDGET_H #include <QWidget> #include <QThread> QT_BEGIN_NAMESPACE class QTimer; class Thread; class Widget : public QWidget { Q_OBJECT public: Widget(QWidget *parent = 0); ~Widget(); }; class Thread : public QThread { Q_OBJECT public: Thread(QObject* parent = nullptr); public slots: void display(); protected: void run(); }; class Calc : public QObject { Q_OBJECT public: Calc(int start, int step); public slots: void display(); private: int m_cur; const int m_step; }; QT_END_NAMESPACE #endif // WIDGET_H #include "widget.h" #include <QTimer> #include <QDebug> Widget::Widget(QWidget *parent) : QWidget(parent) { /* Thread* thread = new Thread; //此处设父指针为this,关闭应用程序时会发生崩溃 thread->start(); */ Calc* c = new Calc(0, 1); Q_UNUSED(c); } Widget::~Widget() { } //构造函数,继承QThread Thread::Thread(QObject *parent) : QThread(parent) { } void Thread::display() { qDebug() << "running in thread"; } void Thread::run() { QTimer* timer = new QTimer; //多线程环境中,此处设父指针为this,会导致创建线程失败,定时器可用 connect(timer, SIGNAL(timeout()), this, SLOT(display())); timer->start(1000); exec(); //开启事件循环 } Calc::Calc(int start, int step) : m_cur(start) , m_step(step) { QThread* thread = new QThread; moveToThread(thread); thread->start(); QTimer* timer = new QTimer; //多线程环境中,此处设父指针为this,会导致创建线程失败,定时器可用 connect(timer, SIGNAL(timeout()), this, SLOT(display())); timer->start(1000); } void Calc::display() { qDebug() << m_cur; m_cur += m_step; }