zoukankan      html  css  js  c++  java
  • 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;
    }
  • 相关阅读:
    java.util.logging.Logger使用详解
    JAVA7新增的对自动关闭资源的try语句的问题
    java的"1"+"asd"的底层
    oracle的存储过程与函数
    java.exe和javaw.exe有什么区别?
    需要看的知识点
    关于String-StringBuffer-Stringbuilder的知识点
    tomcat是什么?
    生产系统总结
    less
  • 原文地址:https://www.cnblogs.com/zhugaopeng/p/9092193.html
Copyright © 2011-2022 走看看