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;
}
原文地址:https://www.cnblogs.com/zhugaopeng/p/9092193.html