• Qt5开发从入门到精通——第十二篇一节(Qt5 事件处理及实例——多线程及简单实例)


    提示:欢迎小伙伴的点评✨✨,相互学习c/c++应用开发。🍳🍳🍳
    博主🧑🧑 本着开源的精神交流Qt开发的经验、将持续更新续章,为社区贡献博主自身的开源精神👩‍🚀


    前言

    本章节会给大家带来Qt5 事件处理及实例——多线程及简单实例。


    一、多线程及简单实例概述

    通常情况下,应用程序都是在一个线程中执行操作。但是,当调用一个耗时操作(例如,大批量 I/0 或大量矩阵变换等 CPU 密集操作)时,用户界面常常会冻结。而使用多线程可解决这一问题。
    多线程具有以下优势。
    (1) 提高应用程序的响应速度。这对于开发图形界面的程序尤为重要,当一个操作耗时很
    长时,整个系统都会等待这个操作,程序就不能响应键盘、鼠标、菜单等的操作,而使用多线程技术可将耗时长的操作置于一个新的线程,从而避免出现以上问题。
    (2) 使多 CPU 系统更加有效。当线程数不大于 CPU 数目时,操作系统可以调度不同的线
    程运行于不同的 CPU 上。
    (3) 改善程序结构。一个既长又复杂的进程可以考虑分为多个线程,成为独立或半独立的
    运行部分,这样有利于代码的理解和维护。
    多线程程序具有以下特点。
    (1) 多线程程序的行为无法预期,当多次执行上述程序时,每次的运行结果都可能不同。
    (2) 多线程的执行顺序无法保证,它与操作系统的调度策略和线程优先级等因素有关。
    (3) 多线程的切换可能发生在任何时刻、任何地点。
    (4) 由于多线程对代码的敏感度高,因此对代码的细微修改都可能产生意想不到的结果。
    基于以上这些特点,为了有效地使用线程,开发人员必须对其进行控制。

    二、效果实例

    图一
    在这里插入图片描述
    图二
    在这里插入图片描述

    三、原码实例

    threaddlg.h

    #ifndef THREADDLG_H
    #define THREADDLG_H
    
    #include 
    #include 
    #include "workthread.h"
    #define MAXSIZE 2
    class ThreadDlg : public QDialog
    {
        Q_OBJECT
    
    public:
        ThreadDlg(QWidget *parent = 0);
        ~ThreadDlg();
    private:
        QPushButton *startBtn;
        QPushButton *stopBtn;
        QPushButton *quitBtn;
    
    public slots:
        void slotStart();
        void slotStop();
    private:
        WorkThread *workThread[MAXSIZE];
    };
    
    #endif // THREADDLG_H
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28

    workthread.h

    #ifndef WORKTHREAD_H
    #define WORKTHREAD_H
    
    #include 
    
    /*工作线程 WorkThread 类继承自 QThread 类*/
    class WorkThread : public QThread
    {
    public:
        WorkThread();
    protected :
    void run();
    
    };
    
    #endif // WORKTHREAD_H
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    main.cpp

    #include "threaddlg.h"
    #include 
    
    int main(int argc, char *argv[])
    {
        QApplication a(argc, argv);
        ThreadDlg w;
        w.show();
    
        return a.exec();
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    threaddlg.cpp

    #include "threaddlg.h"
    #include 
    
    ThreadDlg::ThreadDlg(QWidget *parent)
        : QDialog(parent)
    {
        setWindowTitle(tr(" 线程"));
        startBtn = new QPushButton(tr("开始"));
        stopBtn = new QPushButton(tr(" 停止 ")) ;
        quitBtn = new QPushButton(tr(" 退出")) ;
        QHBoxLayout *mainLayout = new QHBoxLayout(this);
        mainLayout->addWidget(startBtn);
        mainLayout->addWidget(stopBtn);
        mainLayout->addWidget(quitBtn);
        connect (startBtn, SIGNAL(clicked()), this, SLOT (slotStart ()));
        connect (stopBtn, SIGNAL(clicked()), this, SLOT (slotStop ()));
        connect (quitBtn, SIGNAL(clicked()) , this, SLOT (close ()));
    }
    
    ThreadDlg::~ThreadDlg()
    {
    
    }
    
    /*这里使用两个循环,目的是使新建
    的线程尽可能同时开始执行*/
    void ThreadDlg::slotStart()
    {
        for(int i=0;i<MAXSIZE;i++)
        {
            /* 创建指定数目的 WorkThread 线程,并将 WorkThread实例的指针保存在指针数组 workThread 中。*/
            workThread[i] =new WorkThread();
        }
    
        for(int i=0;i<MAXSIZE;i++)
        {
            /*调用 QThread 基类的 start()函数,此函数将启动 run()函数,从而使线程开始真正运行。*/
            workThread[i] ->start();
        }
        startBtn->setEnabled(false);
        stopBtn->setEnabled(true);
    }
    
    /*当用户单击“停止”按钮时,将调用槽函数 slotStop() */
    void ThreadDlg::slotStop ()
    {
        for(int i=0;i<MAXSIZE;i++)
        {
            workThread [i]->terminate();
            workThread[i]->wait();
        }
        startBtn->setEnabled(true);
        stopBtn->setEnabled(false);
    
        /*其中, workThread[i]->terminate() 、 workThread[i]->waitO: 调用 QThread 基类的 terminate()
         *函数,依次终止保存在 workThread[]数组中的 WorkThread 类实例。但是, terminate()函数并不会
         *立刻终止这个线程,该线程何时终止取决千操作系统的调度策略。因此,程序紧接着调用了
         *QThread 基类的 wait() 函数,它使线程阻塞等待直到退出或超时。
         */
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61

    workthread.cpp

    #include "workthread.h"
    #include  
    WorkThread::WorkThread()
    {
    
    }
    
    /*run() 函数实际上是一个死循环,它不停地打印数字 0-9 。为了显示效果明显,程序将每一个数字重复打印 8 次。*/
    void WorkThread::run()
    {    
        while (true)
        {
            for(int n=0;n<10;n++)
            qDebug()<<n<<n<<n<<n<<n<<n<<n<<n;
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    四、总结

    Qt5 事件处理及实例——多线程及简单实例会在应用程序开发中经常用到的。

  • 相关阅读:
    使用 Redis 构建轻量的向量数据库应用:图片搜索引擎(二)
    创建单例模式的方法
    【无标题】
    前端之Bootstrap框架
    qemu简单安装虚拟机(vnc方式,CentOS7.9)
    MySQL系列-win10安装MySQL
    【JAVA问题解决方案】02.Freemarker导出Excel超出上限分表解决方案
    Xception:使用深度可分离卷积的深度学习算法
    UGUI学习笔记(十一)自制优化版滚动视图
    红队专题-开源漏扫-巡风xunfeng源码剖析与应用
  • 原文地址:https://blog.csdn.net/weixin_44759598/article/details/127988956