linux系统中QT里面多线程的使用方法

news2024/11/27 2:31:10

      大家好,今天主要和大脚聊一聊,如何使用QT中的多线程的方法。

 

第一:多线程基本简介

       QThread 线程类是实现多线程的核心类。Qt 有两种多线程的方法,其中一种是继承 QThread 的 run()函数,另外一种是把一个继承于 QObject 的类转移到一个 Thread 里。Qt4.8 之前都是使用继承 QThread run()这种方法,但是 Qt4.8 之后,Qt 官方建议使用第二种方法。两种方法区 别不大,用起来都比较方便,但继承 QObject 的方法更加灵活。所以 Qt 的帮助文档里给的参考是先给继承 QObject 的类,然后再给继承 QThread 的类。另外 Qt 提供了 QMutexQMutexLockerQReadLocker QWriteLocker 等类用于线程之间的同步,详细可以看 Qt 的帮助文档。

        

        通过上面的图我们可以看到,主线程内有很多方法在主线程内,但是子线程,只有 run() 方法是在子线程里的。run() 方法是继承于 QThread 类的方法,用户需要重写这个方法,一般是把耗时的操作写在这个 run() 方法里面。

第二:应用实例实现

         通过 QThread 类继承线程,然后在 MainWindow 类里使用。通过点击一个按钮开启线程。当线程执行完成时,会发送 resultReady(const QString &s)信号给主线程。
1 #ifndef MAINWINDOW_H
2 #define MAINWINDOW_H
3
4 #include <QMainWindow>
5 #include <QThread>
6 #include <QDebug>
7 #include <QPushButton>
8
9 /* 使用下面声明的 WorkerThread 线程类 */
10 class WorkerThread;
11
12 class MainWindow : public QMainWindow
13 {
14 Q_OBJECT
15
16 public:
17 MainWindow(QWidget *parent = nullptr);
18 ~MainWindow();
19
20 private:
21 /* 在 MainWindow 类里声明对象 */
22 WorkerThread *workerThread;
23
24 /* 声明一个按钮,使用此按钮点击后开启线程 */
25 QPushButton *pushButton;
26
27 private slots:
28 /* 槽函数,用于接收线程发送的信号 */
29 void handleResults(const QString &result);
30
31 /* 点击按钮开启线程 */
32 void pushButtonClicked();
33 };
34
35 /* 新建一个 WorkerThread 类继承于 QThread */
36 class WorkerThread : public QThread
37 {
38 /* 用到信号槽即需要此宏定义 */
39 Q_OBJECT
40
41 public:
42 WorkerThread(QWidget *parent = nullptr) {
43 Q_UNUSED(parent);
44 }
45
46 /* 重写 run 方法,继承 QThread 的类,只有 run 方法是在新的线程里 */
47 void run() override {
48 QString result = "线程开启成功";
49
50 /* 这里写上比较耗时的操作 */
51 // ...
52 // 延时 2s,把延时 2s 当作耗时操作
53 sleep(2);
54
55 /* 发送结果准备好的信号 */
56 emit resultReady(result);
57 }
58
59 signals:
60 /* 声明一个信号,译结果准确好的信号 */
61 void resultReady(const QString &s);
62 };
63
64 #endif // MAINWINDOW_H
65
36 行,声明一个 WorkerThread 的类继承 QThread 类,这里是参考 Qt QThread 类的帮
助文档的写法。
47 行,重写 run() 方法,这里很重要。把耗时操作写于此,本例相当于一个继承 QThread
类线程模板了。

第三:源文件的代码具体实现

1 #include "mainwindow.h"
2
3 MainWindow::MainWindow(QWidget *parent)
4 : QMainWindow(parent)
5 {
6 /* 设置位置与大小 */
7 this->setGeometry(0, 0, 800, 480);
8
9 /* 对象实例化 */
10 pushButton = new QPushButton(this);
11 workerThread = new WorkerThread(this);
12
13 /* 按钮设置大小与文本 */
14 pushButton->resize(100, 40);
15 pushButton->setText("开启线程");
16
17 /* 信号槽连接 */
18 connect(workerThread, SIGNAL(resultReady(QString)),
19 this, SLOT(handleResults(QString)));
20 connect(pushButton, SIGNAL(clicked()),
21 this, SLOT(pushButtonClicked()));
22 }
23
24 MainWindow::~MainWindow()
25 {
26 /* 进程退出,注意本例 run()方法没写循环,此方法需要有循环才生效 */
27 workerThread->quit();
28
29 /* 阻塞等待 2000ms 检查一次进程是否已经退出 */
30 if (workerThread->wait(2000)) {
31 qDebug()<<"线程已经结束!"<<endl;
32 }
33 }
34
35 void MainWindow::handleResults(const QString &result)
36 {
37 /* 打印出线程发送过来的结果 */
38 qDebug()<<result<<endl;
39 }
40
41 void MainWindow::pushButtonClicked()
42 {
43 /* 检查线程是否在运行,如果没有则开始运行 */
44 if (!workerThread->isRunning())
45 workerThread->start();
46 }
11 行,线程对象实例化, Qt 使用 C++ 基本都是对象编程, Qt 线程也不例外。所以我们
也是用对象来管理线程的。
24~33 行,在 MainWindow 的析构函数里退出线程,然后判断线程是否退出成功。因为
我们这个线程是没有循环操作的,直接点击按钮开启线程后,做了 2s 延时操作后就完成了。所
以我们在析构函数里直接退出没有关系。
41~46 行,按钮点击后开启线程,首先我们得判断这个线程是否在运行,如果不在运行
我们则开始线程,开始线程用 start() 方法,它会调用重写的 run() 函数的。

第四:程序运行效果

        点击开启线程按钮后,延时 2s 后,Qt Creator 的应用程序输出窗口打印出“线程开启成功”。
2s 内多次点击按钮则不会重复开启线程,因为线程在这 2s 内还在运行。同时我们可以看到
点击按钮没卡顿现象。因为这个延时操作是在我们创建的线程里运行的,而 pushButton 是在主
线程里的,通过点击按钮控制子线程的运行。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/153614.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Excel教程

目录 1.设置Excel界面以及保存Excel 1.1 自定义快速访问工具栏 1.2 自定义功能区的使用 1.2.1 自定义选项卡 1.3 自定义页面 1.4 保存时设置文件密码 2.常用的高效操作 2.1 快速填充 2.1.1 快速填充实现拆分重组 2.2 快速分析数据 2.2.1 格式化​编辑 2.2.2 图表&#xff0c…

yolov5 引入RepVGG模型结构

&#xff08;一&#xff09;前情 这个工作已经有大佬用在自己的工程里了&#xff0c;他的帖子链接&#xff1a;https://blog.csdn.net/weixin_45829462/article/details/120372921 但他的这个lite主要不是研究repvgg的&#xff0c;是做移动端的&#xff0c;但是里面加了这个re…

【BP靶场portswigger-服务端8】文件上传漏洞-7个实验(全)

前言&#xff1a; 介绍&#xff1a; 博主&#xff1a;网络安全领域狂热爱好者&#xff08;承诺在CSDN永久无偿分享文章&#xff09;。 殊荣&#xff1a;CSDN网络安全领域优质创作者&#xff0c;2022年双十一业务安全保卫战-某厂第一名&#xff0c;某厂特邀数字业务安全研究员&…

Linux应用编程---13.网络编程

Linux应用编程—13.网络编程 ​ 网络编程要熟悉一些计算机网络有关的名词&#xff0c;可以先做了解&#xff0c;后续实际开发在深入研究&#xff0c;自上而下学习。与本次Linux应用编程有关的就是TCP与UDP协议。简明概念如下图1所示。 图1 计算机网络体系结构 ​ 前面学习的进…

数控机床各种加工模式以及英文简写

AUTO&#xff08;自动模式&#xff09; 机床自动运行加工程序&#xff0c;对零件进行加工。前提是所编的程序经过试验后是可行的&#xff0c;而且是加工出来的件经过检验后是合格的&#xff0c;才可以使用该程序。 EDIT&#xff08;编辑模式&#xff09; 在此模式下&#xff…

Spring Boot集成第三方登录之微博登录

准备工作 微博开放平台&#xff1a;https://open.weibo.com/ 网站接入 登陆微博开放平台&#xff0c;进入微连接&#xff0c;选择网站接入 点击立即接入 开发者信息认证 填写开发者信息与身份认证信息 创建应用 开发者信息认证通过后即可创建应用。 应用创建成功后会得到app …

哪种台灯质量好又实惠?性价比最高的护眼台灯

l 只要台灯质量过关就是及格的第一步&#xff0c;首先就是有3C质量认证&#xff0c;符合国A或国AA照度标准。l 显色也会是很重要的&#xff0c;光源品质高的产品&#xff0c;显色性不会低于Ra90的&#xff0c;太阳光的显色指数&#xff1d;100&#xff0c;那么意味着显色指数越…

一文详解Paramiko安装与使用

项目要求 定期向特定服务器传输软件运行状况文件&#xff08;基于SFTP&#xff09;&#xff0c;因此计划写一个Python脚本&#xff0c;该脚本首先要定期读取产品运营数据&#xff0c;然后按要求生成数据文件&#xff0c;最后通过 Paramiko 上传到SFTP服务器。 这篇文章是我在实…

【Spring源码】19. 没合适的构造器?找determineCandidateConstructors()!

上篇介绍了instantiateBean()&#xff08;其实这个方法在后面还会再次被调用&#xff09;如果在前两篇的内容结束后都还未获取到构造函数&#xff0c;那么则继续向下执行&#xff0c;调用determineConstructorsFromBeanPostProcessors()方法determineConstructorsFromBeanPostP…

如何确定梯度消失/爆炸和解决梯度消失/爆炸

1、梯度消失的原因和表现1.1、梯度消失的原因&#xff1a;在深层网络中&#xff0c;如果激活函数的导数小于1&#xff0c;根据链式求导法则&#xff0c;靠近输入层的参数的梯度因为乘了很多的小于1的数而越来越小&#xff0c;最终就会趋近于0&#xff0c;例如sigmoid函数&#…

【C++常用算法】STL基础语法学习 | 算数生成算法集合算法

目录 ●accumulate ●fill ●set_intersection ●set_union ●set_difference ●accumulate 1.功能描述&#xff1a; 计算容器内元素累计总和 2.查看accumulate定义下底层代码的函数原型&#xff1a; 3.向vector容器中插入0~100&#xff0c;使用accumulate算法去计算其和…

RabbitMQ的五大常用模型介绍以及SpringAMQP的使用

目录MQ的介绍使用MQ的好处技术对比RabbitMQ的使用Docker启动MQ角色介绍五大常用消息模型使用SpringAMQP模板简单队列模型工作队列模型广播模型 Fanout路由模式 Direct主题模式 TopicMQ的介绍 MQ&#xff0c;MessageQuene即 消息队列&#xff0c;是程序与程序之间的异步通信一种…

spring的IOC与DI小案例

注&#xff1a;本博客用于自学&#xff0c;如有错误&#xff0c;敬请指正。 一、首先要了解的概念 IOC是一种思想&#xff1a;将创建、初始化对象的控制权交给IOC容器 IOC容器&#xff1a;用来装对象的容器 Bean&#xff1a;IOC容器中装的对象 DI&#xff1a;将IOC容器种Bean…

打破光缆资源管理难题

如何打破光缆资源管理难题&#xff0c;将光缆资源价值最大化&#xff0c;相信是每个运维人都关心的焦点问题。 一、背景 全业务发展到今天&#xff0c;我们逐渐意识到&#xff0c;市场竞争的核心已聚焦到传输资源。从拼资源总量到拼资源管理&#xff0c;传统的运维管理模式面临…

【每日一题】【LeetCode】【第九天】存在重复元素

解决之路 题目描述 测试案例&#xff08;部分&#xff09; 第一次 关键就是看是否有重复元素&#xff0c;暴力解法就是双循环&#xff0c;然后有相同元素就返回True&#xff0c;否则就等循环结束&#xff0c;返回False。 但是自己想到了另一个只需要一个循环的解法。用一个…

C++11 简化 “策略模式” 的一种思路

策略模式是一种定义一系列算法的模式&#xff0c;从概念上看&#xff0c;所有这些算法完成的都是相同接口的工作&#xff08;只是实现不同&#xff09;&#xff0c;它可以以相同的方式调用所有的算法&#xff0c;减少了各种算法类与使用算法的类之间的耦合。实践中只要在分析过…

开发者工具中performance面板解析

目录总览设置面板网络性能总览图火焰图&#xff1a;耗费的时间相关信息总览 如图&#xff0c;主要分为以下4个方面 设置面板 1&#xff0c; 不刷新页面进行录制 2&#xff0c;刷新页面进行录制 3&#xff0c;删除性能展示页面 4&#xff0c;上传本地的性能页面 5&#xff0c…

若依mybatis升级mybatis-plus,其他也适用

若依mybatis升级mybatis-plus,其他也适用 本文档记录若依mybatis升级plus,其他也类似 文章目录若依mybatis升级mybatis-plus,其他也适用第一步 修改ruoyi-common的pom.xml第二步 修改ruoyi-admin的application.yml第三步 修改ruoyi-framework的MyBatisConfig.java开始测试1. 修…

一、计算机系统概论

文章目录一、计算机系统简介1.计算机软硬件概念2.计算机系统的层次结构&#xff08;1&#xff09;现代计算机&#xff08;2&#xff09;发展&#xff08;3&#xff09;软硬件分布3.计算机组成和计算机体系结构二、计算机的基本组成1.冯诺依曼计算器2.计算机硬件框图3.计算机工作…

android架构拆分方案-编译相关方案与技术

接上文https://blog.csdn.net/dongyi1988/article/details/128617738直接拆分那么在代码和做包过程中&#xff0c;需要用到分仓&#xff0c;super.img、boot、OTA升级包的拆分与组合&#xff0c;vendor与system相关依赖处理&#xff0c;开机验证链还必须给镜像签名。代码管理定…