qt线程介绍
目录
介绍
线程类 QThread
方式1
方式2
案例
线程资源释放
介绍
qt为多线程提供了完美的支持,实现多线程一般是从从QTHread中继承定义自己的线程类,QT也提供了QMutexLocker,QwaitCondition等类实现线程同步,与Linux系统或C++中的线程库类似。这里简单介绍下多线程的创建。
- 默认的线程在Qt中称之为窗口线程,也叫主线程,负责窗口事件处理或者窗口控件数据的更新
- 子线程负责后台的业务逻辑处理,子线程中不能对窗口对象做任何操作,这些事情需要交给窗口线程处理
- 主线程和子线程之间如果要进行数据的传递,需要使用Qt中的信号槽机制
线程类 QThread
常用API:
[virtual protected] void QThread::run();
run()是一个虚函数,如果想让创建的子线程执行某个任务,需要写一个子类让其继承QThread,并且在子类中重写父类的run()方法,函数体就是对应的任务处理流程,当前线程对象调用槽函数start()启动子线程,当子线程被启动,这个run()函数也就在线程内部被调用了。
信号与槽函数:
// 线程中执行的任务完成了, 发出该信号
[signal] void QThread::finished();
// 开始工作之前发出这个信号, 一般不使用
[signal] void QThread::started();[slot] void QThread::quit();
// 启动子线程
[slot] void QThread::start(Priority priority = InheritPriority);
// 线程退出, 可能是会马上终止线程, 一般情况下不使用这个函数
[slot] void QThread::terminate();
方式1
创建一个线程类的子类,让其继承QT中的线程类 QThread,重写父类的 run() 方法,启动子线程, 调用 start() 方法。
举例:
#ifndef MYTHREAD_H
#define MYTHREAD_H#include <QObject>
#include<QThread>class MyThread : public QThread
{Q_OBJECT
public:explicit MyThread(QObject *parent = nullptr);
protected:void run();
signals:void curNumber(int num);
};#endif // MYTHREAD_H
#include "mythread.h"
#include<QDebug>
MyThread::MyThread(QObject *parent)
{
}void MyThread::run()
{qDebug() << "当前线程对象的地址: " << QThread::currentThread();int num = 0;while(1){emit curNumber(num++);//子线程每秒发出一次信号if(num == 10000000){break;}QThread::usleep(1);}qDebug() << "run() 执行完毕, 子线程退出...";}
MainWindow::MainWindow(QWidget *parent): QMainWindow(parent), ui(new Ui::MainWindow)
{ui->setupUi(this);qDebug() << "主线程对象地址: " << QThread::currentThread();MyThread* m=new MyThread;connect(m, &MyThread::curNumber, this, [=](int num)//子线程每秒发出一次信号{ui->label->setNum(num);});connect(ui->pushButton, &QPushButton::clicked, this, [=](){// 启动子线程m ->start();});
}MainWindow::~MainWindow()
{delete ui;
}
方式2
- 创建一个新的类A,让这个类从QObject派生,这个类中添加一个公共的成员函数来处理对应的任务
- 在主线程中创建一个QThread对象
- 在主线程中创建工作的类对象A(不能指定父对象)
- 将对象A移动到创建的子线程对象中, 需要调用QObject类提供的moveToThread()方法
- 启动子线程,调用 start(), 这时候线程启动了, 但是移动到线程中的对象并没有工作
- 调用MyWork类对象的工作函数,让这个函数开始执行。
例如:
#ifndef WORK_H
#define WORK_H
#include <QObject>class Work : public QObject
{Q_OBJECT
public:explicit Work(QObject *parent = nullptr);void Working();
signals:void curNumber(int num);};
#endif // WORK_H
#include "work.h"
#include<QDebug>
#include<QThread>
Work::Work(QObject *parent): QObject{parent}
{
}void Work::Working()
{qDebug() << "当前线程对象的地址: " << QThread::currentThread();int num = 0;while(1){emit curNumber(num++);//子线程每秒发出一次信号if(num == 10000000){break;}QThread::usleep(1);}qDebug() << "run() 执行完毕, 子线程退出...";
}
MainWindow::MainWindow(QWidget *parent): QMainWindow(parent), ui(new Ui::MainWindow)
{ui->setupUi(this);qDebug() << "主线程对象地址: " << QThread::currentThread();QThread* sub = new QThread;//创建线程对象Work* w=new Work; //创建工作对象,该对象包含业务处理方法,不要指定给创建的对象指定父对象w->moveToThread(sub); //将工作对象移动到子线程中sub->start();connect(ui->startBtn, &QPushButton::clicked, w,&Work::Working);// 显示数据connect(w, &Work::curNumber, this, [=](int num){ui->label->setNum(num);});
}
案例
在一个子线程程中随机生成1000个数,将这些数据交给另一个子线程去排序,后面将排序的结果返回给主线程,主线程再将数据输出到窗口中。
这里采用方案1进行演示:
生成随机数线程:
class Genera : public QThread //该类来生成随机数
{Q_OBJECT
public:explicit Genera(QObject *parent = nullptr);void getnum(int k);
protected:void run();//重写run方法,生成随机数
private:int num_; //获取主线程传来的数据,这里为生成随机数的个数signals:void sendnum(QVector<int> v);//当随机数生成完后,发射该信号,将数据传给主线程和排序线程
};Genera::Genera(QObject *parent): QThread{parent}
{
}
void Genera::getnum(int k)
{num_=k;
}
void Genera::run()
{qDebug()<<"当前线程是"<<" "<<QThread::currentThread();QVector<int> v;QElapsedTimer q;q.start();for(int i=0;i<num_;i++){v.push_back(qrand()%10000);}int m=q.elapsed();qDebug()<<"生成随机的时间是"<<" "<<m;emit sendnum(v);}
排序线程:
class BubbleSort : public QThread //该类来生成随机数
{Q_OBJECT
public:explicit BubbleSort(QObject *parent = nullptr);void getnum(QVector<int>);//获取生成随机数线程传来的数据
protected:void run();//进行排序
private:QVector<int> v;signals:void Finish(QVector<int> v);//排序完成后发射该信号,将排序结果给主线程
};BubbleSort::BubbleSort(QObject *parent): QThread{parent}
{
}
void BubbleSort::getnum(QVector<int> list)
{v=list;
}
void BubbleSort::run()
{qDebug()<<"当前线程是"<<" "<<QThread::currentThread();QElapsedTimer q;q.start();for(int i=0;i<v.size();i++){for(int j=0;j<v.size()-i-1;j++){if(v[j]>v[j+1]){int tmp=v[j+1];v[j+1]=v[j];v[j]=tmp;}}}int m=q.elapsed();qDebug()<<"排序的时间是"<<" "<<m;emit Finish(v);
}
主线程:
class MainWindow : public QMainWindow
{Q_OBJECTpublic:MainWindow(QWidget *parent = nullptr);~MainWindow();
signals:void starting(int num);//生成随机数的个数private:Ui::MainWindow *ui;
};
#endif // MAINWINDOW_HMainWindow::MainWindow(QWidget *parent): QMainWindow(parent), ui(new Ui::MainWindow)
{ui->setupUi(this);//创建子线程Genera * g=new Genera;//生成随机数BubbleSort* b=new BubbleSort;//排序connect(this,&MainWindow::starting,g,&Genera::getnum);//启动子线程connect(ui->pushButton,&QPushButton::clicked,this,[=](){emit starting(1000);//发射该信号,将生成随机数的个数传给子线程g->start();});connect(g,&Genera::sendnum,b,&BubbleSort::getnum);//排序线程接受生成随机数线程传来的数据//接受子线程传来的排序数connect(g,&Genera::sendnum,this,[=](QVector<int> v){//说明随机生成数已生成好b->start();for(int i=0;i<v.size();i++){ui->listWidget->addItem(QString::number(v.at(i)));}});connect(b,&BubbleSort::Finish,this,[=](QVector<int> v){for(int i=0;i<v.size();i++){ui->listWidget_2->addItem(QString::number(v.at(i)));}});
}MainWindow::~MainWindow()
{delete ui;
}
结果:
线程资源释放
1.创建线程时,给它指明父对象,让其添加到对象树列表中。
2.手动释放,调用quit,wait,delete:例如,在上面的代码中,new出来的时局部变量:
connect(this,&MainWindow::destroyed,this,[=](){g->quit();g->wait();g->deleteLater();//类似与c++中delete});
相关文章:
qt线程介绍
目录 介绍 线程类 QThread 方式1 方式2 案例 线程资源释放 介绍 qt为多线程提供了完美的支持,实现多线程一般是从从QTHread中继承定义自己的线程类,QT也提供了QMutexLocker,QwaitCondition等类实现线程同步,与Linux系统或C中的线程库类似…...
记一次用dataframe进行数据清理
总结一下dataframe读取数据库,以及整理数据的过程。分为三个部分:数据读取,数据整理以及数据写入。 1、数据读取 从csv读取读取数据,使用pandas读的read_csv函数,传入两个参数,分别是path文件路径&#x…...
《Jetpack Compose从入门到实战》 第二章 了解常用UI组件
目录 常用的基础组件文字组件图片组件按钮组件选择器组件对话框组件进度条组件 常用的布局组件布局Scaffold脚手架 列表 书附代码 Google的图标库 常用的基础组件 文字组件 Composable fun TestText() {Column(modifier Modifier.verticalScroll(state rememberScrollState…...
Vue3 引入使用 vant组件详解
目录 Vue3 引入使用 vant组件详解1.安装2.引入2.1 全局引入2.2 按需引入2.2.1 vite项目:vite.config.js2.2.2 Webpack项目:webpack.config.js2.2.3 配置在vue.config.js中 3.使用 Vue3 引入使用 vant组件详解 Vant是一个强大的移动端组件库,目前Vant 官…...
NOSQL Redis Ubuntu系列 常用的配置 及密码登录
查看Ubuntu 版本 uname -a 配置redis.conf 查看redis 是否安装成功 ps -ef | grep redis 查看redis 服务状态 service redis status 查看redis 默认安装的路径 whereis redis #sudo vim /etc/redis.conf redis 密码登录...
C语言解析GPS源数据
文章目录 一、GPS数据格式介绍二、GPS字段含义三、C语言解析数据代码3.1 解析每个字段数据3.2 解析定位数据 一、GPS数据格式介绍 GPS(全球定位系统)数据格式常见的是NMEA 0183格式,NMEA 0183格式是一种用于导航设备间传输数据的标准格式&am…...
【论文阅读】(CVPR2023)用于半监督医学图像分割的双向复制粘贴
目录 前言方法BCPMean-teacher and Traning StrategyPre-Training via Copy-PasteBidirectional Copy-Paste ImagesBidirectional Copy-Paste Supervisory Signals Loss FunctionTesting Phase 结论 先看这个图,感觉比较清晰。它整个的思路就是把有标签的图片和无标…...
[Linux 基础] 一篇带你了解linux权限问题
文章目录 1、Linux下的两种用户2、文件类型和访问权限(事物属性)2.1 Linux下的文件类型2.2 基本权限2.3 文件权限值的表示方法(1)字符表示方法(2)8进制数值表示方法 2.4 文件访问权限的相关设置方法(1) chm…...
FPGA project :HDMI
实验目标:驱动HdMI显示十色等宽彩条。 本实验的重点是: 1掌握TMDS通信协议。 2rgb565转rgb888。 3编写HDMI驱动程序。 4学会看流程图编写代码。 值得注意的事情 1注意数据与解析数据的信号(比如传入的数据中0或者1的个数)&…...
基于微信小程序的物流快递信息查询平台同城急送小程序(亮点:寄件、发票申请、在线聊天)
文章目录 前言系统主要功能:具体实现截图论文参考详细视频演示为什么选择我自己的网站自己的小程序(小蔡coding)有保障的售后福利 代码参考源码获取 前言 💗博主介绍:✌全网粉丝10W,CSDN特邀作者、博客专家、CSDN新星计…...
idea插件推荐
目录 一、插件安装方式 file->settings->plugins->macketplace 各个版本IDE插件界面略有不同,不一一赘述 二、常用插件 1、Background Image Plus 推荐指数:★★★★☆ 这款插件并不能直接提高你的开发效率,但是可以让你面对的ID…...
Arcgis快速计算NDVI
Arcgis快速计算NDVI 一、问题描述 如何使用Arcgis像ENVI一样波段计算NDVI的值,事实上,Arcgis更快速一些。 二、操作步骤 首先准备好影像 打开窗口-影像分析 点击左上角 点击确定 (发现自己使用的遥感影像不对劲,是计算好了…...
SpringCloud Alibaba - 基于 FeignClient 整合 Sentinel,实现“线程隔离”和“熔断降级”
目录 一、FeignClient 整合 Sentinel 1.1、整合原因 1.2、实现步骤 1.2.1、修改 OrderService 中的 application.yml 文件 1.2.2、给 FeignClient 编写失败后的降级逻辑 二、线程隔离 2.1、线程隔离的两种方式 2.1.1、线程池隔离 2.1.2、信号量隔离(Sentin…...
Acwing 906. 区间分组
Acwing 906. 区间分组 知识点题目描述思路讲解代码展示 知识点 贪心 题目描述 思路讲解 这段代码是用来维护一个最小堆,以确保右边界不相交的区间被正确地保留在堆中。让我详细解释这段代码: heap.empty():这个条件检查最小堆 heap 是否为…...
阿里云 Oss 权限控制
前言 最近公司的私有 Oss 服务满了,且 Oss 地址需要设置权限,只有当前系统的登录用户才能访问 Oss 下载地址。一开始想着用 Nginx 做个转发来着,Nginx 每当检测当前请求包含特定的 Oss 地址就转发到我们的统一鉴权接口上去,但是紧…...
CSS详细基础(六)边框样式
本期是CSS基础的最后一篇~ 目录 一.border属性 二.边框属性复合写法 三.CSS修改表格标签 四.内边距属性 五.外边距属性 六.其他杂例 1.盒子元素水平居中 2.清除网页内外元素边距 3.外边距的合并与塌陷 4.padding不会撑大盒子的情况 七.综合案例——新浪导航栏仿真 …...
支持向量机SVM:从数学原理到实际应用
目录 一、引言背景SVM算法的重要性 二、SVM基础线性分类器简介什么是支持向量?超平面和决策边界SVM的目标函数 三、数学背景和优化拉格朗日乘子法(Lagrange Multipliers)KKT条件核技巧(Kernel Trick)双重问题和主问题&…...
【办公自动化】在Excel中按条件筛选数据并存入新的表(文末送书)
🤵♂️ 个人主页:艾派森的个人主页 ✍🏻作者简介:Python学习者 🐋 希望大家多多支持,我们一起进步!😄 如果文章对你有帮助的话, 欢迎评论 💬点赞Ǵ…...
第三章:最新版零基础学习 PYTHON 教程(第十一节 - Python 运算符—Python 中的any与all)
Any 和 All 是 python 中提供的两个内置函数,用于连续的与/或。Any如果任何一项为 True,则返回 true。如果为空或全部为 false,则返回 False。Any 可以被认为是对所提供的可迭代对象进行 OR 操作的序列。它会短路执行,即一旦知道结果就停止执行。 句法: any(iterable) 函…...
Pytorch单机多卡分布式训练
Pytorch单机多卡分布式训练 数据并行: DP和DDP 这两个都是pytorch下实现多GPU训练的库,DP是pytorch以前实现的库,现在官方更推荐使用DDP,即使是单机训练也比DP快。 DataParallel(DP) 只支持单进程多线程…...
asp.net coremvc+efcore增删改查
下面是一个使用 EF Core 在 ASP.NET Core MVC 中完成增删改查的示例: 创建一个新的 ASP.NET Core MVC 项目。 安装 EF Core 相关的 NuGet 包。在项目文件 (.csproj) 中添加以下依赖项: <ItemGroup><PackageReference Include"Microsoft…...
Java基础面试,什么是面向对象,谈谈你对面向对象的理解
前言 马上就要找工作了,从今天开始一天准备1~2道面试题,来打基础,就从Java基础开始吧。 什么是面向对象,谈谈你对面向对象的理解? 谈到面向对象,那就不得不谈到面向过程。面向过程更加注重的是完成一个任…...
Ubuntu系统初始设置
更换国内源 安装截图工具 安装中文输入法 安装QQ 参考: 安装双系统win10Ubuntu20.04LTS(详细到我自己都害怕) 引导方式磁盘分区方法UEFIGPTLegancyMBR 安装网络助手 sudo apt install net-tools 安装VS Code 使用从官网下载.deb安装包…...
焕新古文化传承之路,AI为古彝文识别赋能
目录 1 古彝文与古典保护 2 古文识别的挑战 2.1 西文与汉文OCR 2.2 古彝文识别难点 3 合合信息:古彝文保护新思路 3.1 图像矫正 3.2 图像增强 3.3 语义理解 3.4 工程技巧 4 总结 1 古彝文与古典保护 彝文指的是云南、贵州、四川等地的彝族人使用的文字&am…...
毛玻璃动画交互效果
效果展示 页面结构组成 从上述的效果展示页面结构来看,页面布局都是比较简单的,只是元素的动画交互比较麻烦。 第一个动画交互是两个圆相互交错来回运动。第二个动画交互是三角绕着圆进行 360 度旋转。 CSS 知识点 animationanimation-delay绝对定位…...
Audio2Face的工作原理
预加载一个3D数字人物模型(Digital Mark),该模型可以通过音频驱动进行面部动画。 用户上传音频文件作为输入。 将音频输入馈送到预训练的深度神经网络中。 Audio2Face加载预制的3d人头mesh 3D数字人物面部模型由大量顶点组成,每个顶点都有xyz坐标。 深度神经网络输入音频特征,…...
【面试题】2023前端面试真题之JS篇
前端面试题库 (面试必备) 推荐:★★★★★ 地址:前端面试题库 表妹一键制作自己的五星红旗国庆头像,超好看 世界上只有一种真正的英雄主义,那就是看清生活的真相之后,依然热爱生活。…...
Mysql 分布式序列算法
接上文 Mysql分库分表 1.分布式序列简介 在分布式系统下,怎么保证ID的生成满足以上需求? ShardingJDBC支持以上两种算法自动生成ID。这里,使用ShardingJDBC让主键ID以雪花算法进行生成,首先配置数据库,因为默认的注…...
Windows/Linux双系统卸载Ubuntu
参考:双系统下完全卸载ubuntu...
asp.net core mvc 视图组件viewComponents
ASP.NET Core MVC 视图组件(View Components)是一种可重用的 UI 组件,用于在视图中呈现某些特定的功能块,例如导航菜单、侧边栏、用户信息等。视图组件提供了一种将视图逻辑与控制器解耦的方式,使视图能够更加灵活、可…...
柳河县建设局网站/最新新闻事件今天疫情
2019独角兽企业重金招聘Python工程师标准>>> 讲述了一个服务如何从配置中心读取文件,配置中心如何从远程git读取配置文件,当服务实例很多时,都从配置中心读取文件,这时可以考虑将配置中心做成一个微服务,将…...
翻译 插件 wordpress/内容营销的4个主要方式
python 列表用法总结 本文为python中最重要的数据类型列表的基础用法笔记。 列表理解 python 是基于值的的自动内存管理方式,每个变量、元素都指向内存地址,修改都是对内存地址操作,不是修改值 。记住这一点对理解python很重要 。 列表是内…...
中国企业公示信息网官网/网站优化的主要内容
近日小米发布了Civi 1S手机,这款手机的最大特点是轻薄,它拥有6.55英寸大屏和4500mAh大容量电池,重量却只有166克,足够轻薄时尚,一改小米数字系列超过200克的遗憾,此举显示出它希望取悦国内年轻人。小米civi…...
天锐绿盾如何做网站限制/dw网页制作教程
1,其实有时候一直在找借口不去思考这个问题,总是以赶项目为由,没有很认真的思考这个问题,为什么我们要在项目中使用MVP模式,自己也用MVP也已经做了两个项目,而且在网上也看了不少的文章,但是感觉…...
网站建设销售策划方案/宁波seo网络推广外包报价
Markdown 区块 Markdown 区块引用是在段落开头使用 > 符号 ,然后后面紧跟一个空格符号: > 区块引用 > 菜鸟教程 > 学的不仅是技术更是梦想 显示结果如下: 另外区块是可以嵌套的,一个 > 符号是最外层,…...
网站界面设计实训报告/网站推广怎么做
今天在国外的网站上看到了很多看似简单却又非常强大的纯CSS绘制的图形,里面有最简单的矩形、圆形和三角形,也有各种常见的多边形,甚至是阴阳太极和网站小图标,真的非常强大,分享给大家。 Square(正方形) #square {widt…...