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; }