QTimer在QThread環境中失效的問題


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

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM