QT 初识多线程
1.QThread线程基础
QThread是Qt线程中有一个公共的抽象类,所有的线程类都是从QThread抽象类中派生的,需要实现QThread中的虚函数run(),通过start()函数来调用run函数。
void run()函数是线程体函数,用于定义线程的功能。
void start()函数是启动函数,用于将线程入口地址设置为run函数。
void terminate()函数用于强制结束线程,不保证数据完整性和资源释放。
QCoreApplication::exec()总是在主线程(执行main()的线程)中被调用,不能从一个QThread中调用。在GUI程序中,主线程也称为GUI线程,是唯一允许执行GUI相关操作的线程。另外,必须在创建一个QThread前创建QApplication(or QCoreApplication)对象。
当线程启动和结束时,QThread会发送信号started()和finished(),可以使用isFinished()和isRunning()来查询线程的状态。
从Qt4.8起,可以释放运行刚刚结束的线程对象,通过连接finished()信号到QObject::deleteLater()槽。
使用wait()来阻塞调用的线程,直到其它线程执行完毕(或者直到指定的时间过去)。
静态函数currentThreadId()和currentThread()返回标识当前正在执行的线程。前者返回线程的ID,后者返回一个线程指针。
要设置线程的名称,可以在启动线程之前调用setObjectName()。如果不调用setObjectName(),线程的名称将是线程对象的运行时类型(QThread子类的类名)。
应用程序的线程称为主线程,额外创建的线程为工作线程。一般在主线程里面创建工作线程,并调用 start() 开始执行工作线程的任务。start()会在内部调用run()函数,进入工作线程的循环,在 run() 函数里调用 exit() 或 quit() 可以结束线程的事件循环,或在主线程里调用 terminate() 强制结束线程。
| QThread类的主要接口 | ||
|---|---|---|
| 类型 | 函数 | 功能 |
| 公共函数 | bool isFinished () | 线程是否结束 |
| bool isRunning () | 线程是否正在运行 | |
| Priority priority () | 返回线程的优先级 | |
| void setPriority (Priority priority) | 设置线程的优先级 | |
| void exit(int returnCode=0) | 退出事件的循环,退出码为returnCode ,0表示成功,否则表示有错误 | |
| bool wait(unsigned long time) | 阻止线程执行,直到线程结束(从run函数返回),或等待时间超过time毫秒 | |
| 公共槽函数 | void quit() | 退出线程的事件循环,并返回代码0,等效于exit() |
| void start(Priority priority) | 内部调用run()函数开始执行线程,操作系统根据priority参数进行调度终止线程的运行,但不是立即结束线程,而是等待操作系统结束线程。使用terminate()之后应使用wait() | |
| void terminate() | ||
| 信号 | void finished() | 在线程结束时发射此信号 |
| void start() | 在线程开始执行、run()函数被调用之前发射此信号 | |
| 静态公共函数 | int idealThreadCount() | 返回系统上能运行的线程的理性个数 |
| void msleep(unsigned long msecs) | 强制当前线程休眠msecs毫秒 | |
| void sleep(unsigned long secs) | 强制当前线程休眠secs秒 | |
| void usleep(unsigned long usecs) | 强制当前线程休眠uecs微秒 | |
| 保护函数 | virtual void run() | start()调用run()函数开始线程任务的执行,所以在run()函数里实现线程的任务功能 |
| int exec() | 由run()函数调用,进入线程的时间循环,等待exit()退出 | |
2.小案例
threaddlg.h
#ifndef THREADDLG_H
#define THREADDLG_H
#define MAXSIZE 5
#include "workthread.h"
#include <QDialog>
#include <QPushButton>QT_BEGIN_NAMESPACE
namespace Ui { class Threaddlg; }
QT_END_NAMESPACEclass Threaddlg : public QDialog
{Q_OBJECTpublic:Threaddlg(QWidget *parent = nullptr);~Threaddlg();private:Ui::Threaddlg *ui;QPushButton *startBtn;QPushButton *stopBtn;QPushButton *quitBtn;WorkThread *workThread[MAXSIZE];public slots:void slotStart();void slotStop();};
#endif // THREADDLG_H
threaddlg.cpp
#include "threaddlg.h"
#include "ui_threaddlg.h"
#include<QHBoxLayout>
Threaddlg::Threaddlg(QWidget *parent): QDialog(parent), ui(new Ui::Threaddlg)
{ui->setupUi(this);setWindowTitle(QStringLiteral("线程"));startBtn=new QPushButton(QStringLiteral("线程"));stopBtn=new QPushButton(QStringLiteral("停止"));quitBtn=new QPushButton(QStringLiteral("退出"));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()
{delete ui;
}void Threaddlg::slotStart()
{for(int i=0;i<MAXSIZE;i++){workThread[i]=new WorkThread; //创建指定数目的WorkThread线程,并将其保存在指针数组workThread中}for(int i=0;i<MAXSIZE;i++){workThread[i]->start();//调用QThread基类start函数,此函数将启动run,使线程开始真正运行}startBtn->setEnabled(false);stopBtn->setEnabled(true);
}void Threaddlg::slotStop()
{for(int i=0;i<MAXSIZE;i++){workThread[i]->terminate();//terminate函数不会立刻终止这个线程,该线程何时终止取决于操作系统的调度策略workThread[i]->wait();//使线程阻塞等待直到退出或超时}startBtn->setEnabled(true);stopBtn->setEnabled(false);
}
WorkThread.h
#ifndef WORKTHREAD_H
#define WORKTHREAD_H
#include <QThread>
#include <QtDebug>
class WorkThread : public QThread
{
public:WorkThread();protected:void run();
};#endif // WORKTHREAD_H
WorkThread.cpp
#include "workthread.h"WorkThread::WorkThread()
{}void WorkThread::run()
{while(true){for(int n=0;n<10;n++)qDebug()<<n<<n<<n<<n<<n<<n<<n;}
}
结果:
1个线程 5个线程


可以看出,一个线程输出是顺序打印的,5个线程也就是多线程的输出结果是乱码打印的
犯了一个很低级的错误
报错为:

原来是因为: 对了,就是clicked没有加括号
![]()
相关文章:
QT 初识多线程
1.QThread线程基础 QThread是Qt线程中有一个公共的抽象类,所有的线程类都是从QThread抽象类中派生的,需要实现QThread中的虚函数run(),通过start()函数来调用run函数。 void run()函数是线程体函数,用于定义线程的功能…...
ubuntu修改用户名和用户密码
1.修改passwd文件 sudo gedit /etc/passwd2.修改shadow文件 sudo gedit /etc/shadow3.修改home目录下文件夹名 mv /home/原用户名/ /home/新用户名4.修改sudo权限(修改group用户组) sudo gedit /etc/group5.修改用户密码 sudo passwd username #修改…...
七、Linux中一些符号的含义和宿主目录的介绍
1、Linux中一些符号的含义 在Linux命令行中,会看到如下一些符号,含义如下。 符号含义. 代表当前目录..代表上一层目录,当前目录的父目录-代表前一个目录,刚才从哪个目录cd过来~代表当前用户的宿主目录/代表根目录$普通用户的命…...
Python基础语法:数据分析利器
⭐️⭐️⭐️⭐️⭐️欢迎来到我的博客⭐️⭐️⭐️⭐️⭐️ 🐴作者:秋无之地 🐴简介:CSDN爬虫、后端、大数据领域创作者。目前从事python爬虫、后端和大数据等相关工作,主要擅长领域有:爬虫、后端、大数据…...
NIO基础
一、NIO基础 Java New IO是从Java1.4版本开始引入的一个新的IO api,可以替代以往的标准IO,NIO相比原来的IO有同样的作用和目的,但是使用的方式完全不一样,NIO是面向缓冲区的,基于通道的IO操作,这也让它比传…...
npm修改为国内镜像
npm config get registry 查看下载地址,默认是https://registry.npmjs.org/ 这是国外的地址,npm下载很慢 npm config set registry https://registry.npmmirror.com/ 使用此指令,修改为淘宝镜像,输入指令后检查是否修改成功 …...
php魔术方法和反序列化漏洞
什么是反序列化漏洞? 漏洞形成的根本原因就是程序没有对用户输入的反序列化字符串进行检测,导致反序列化过程可以被恶意控制,进而造成代码执行、GetShell 等一系列不可控的后果。反序列化漏洞并不是PHP 特有的,也存在于Java、Pyth…...
依赖项的处理与层的创建与注册
依赖项的处理与层的创建与注册 依赖项的处理与层的创建与注册 新问题什么是 layer?layer 的创建与注册 与函数同时创建和绑定单独上传 layer 再绑定函数(推荐) 真正的运行时依赖 注册包的约定与平台强关联的运行时 1. 云端安装依赖2. 本地构建 Amazon Linux 2 容器环境3. 利用…...
Linux CentOS7 系统中添加用户
在linux centOS7系统中,添加用户是管理员的基本操作。作为学习linux系统的基本操作,对添加用户应该多方面了解。 添加用户的命令useradd,跟上用户名,就可以快速创建一个用户。添加一些选项,可以设置更人性化的用户信息…...
八、任务状态
1、任务状态简介 (1)任务状态可以简单的分为运行和非运行。 (2)非运行状态可以细分为:阻塞状态、暂停状态、就绪状态。 2、阻塞状态(Blocked) (1)举例说明:在日常生活的例子中,母亲在电脑前跟同事沟通时,如果同事一直没回复&a…...
基于python的反爬虫技术的研究设计与实现
摘 要 当下的网络是复杂的,网络上的信息非常的丰富,但也造成了大量的信息堆积,特别是大量的重复信息被反复的推送给用户。这是一个流量的时代,很多社会群体都会聚焦具备流量潜力的信息,从而发生蹭热度等行为来提升自己…...
msvcr120.dll放在哪里?怎么修复msvcr120.dll文件
当您在运行某些应用程序或游戏时遇到“msvcr120.dll缺失”错误时,这可能会影响您的使用体验。msvcr120.dll是Microsoft Visual C Redistributable的一部分,并且它提供了程序运行所需的运行时支持,今天我们来讨论一下msvcr120.dl文件缺失了要怎…...
Ubuntu搭建NFS服务
# 服务器初始化步骤 ## 查看磁盘 fdisk -l ## 格式化磁盘,后面的盘符注意对应关系 mkfs.ext4 /dev/sdc ## 新建文件夹 mkdir /mnt/nfs ## 挂载磁盘到创建的文件夹 echo "/dev/sdc /mnt/nfs ext4 defaults 0 0" >> /etc/fstab ## 重新挂载所有分区…...
PHP教学质量评估系统Dreamweaver开发mysql数据库web结构php编程计算机网页代码
一、源码特点 PHP教学质量评估系统是一套完善的web设计系统,对理解php编程开发语言有帮助,系统具有完整的源代码和数据库,系统主要采用B/S模式开发。 代码 https://download.csdn.net/download/qq_41221322/88301983 论文 https://down…...
ElementUI浅尝辄止15:Table 表格
用于展示多条结构类似的数据,可对数据进行排序、筛选、对比或其他自定义操作。 Table组件比较常用,常见于数据查询,报表页面,用来展示表格数据。 1.如何使用? //当el-table元素中注入data对象数组后,在el-t…...
配置LVS_DR模式以及nginx负载均衡
一、配置LVS--DR模式: yum install ipvsadm 配置 LVS 负载均衡服务 ( 1 )手动添加 LVS 转发 1 )用户访问: www.uolookking.com-->vip 192 .168.79.110 ##> 这个是在 DNS 配置 hzitedu 域的 DNS 记录设置 w…...
虚拟数字人直播软件实现带货功能,成为新一代直播风口!
随着短视频带货市场的不断发展,虚拟数字人直播技术逐渐成为热门话题。而在现如今的市场趋势下直播带货则成为了一种火热的营销方式。那么,虚拟数字人直播软件是否可以结合起来,实现无人直播带货的效果呢?让我们来了解一下。 灰豚数…...
01背包问题暴力解法(回溯法)和经典解法
暴力解法(回溯法) import java.util.Arrays; import java.util.Scanner;public class Main {private final static int N 999;public static int SumValue 0;public static int SumWeight 0;public static int OptimalValue 0;public static int O…...
K8S的CKA考试环境和题目
CKA考试这几年来虽然版本在升级,但题目一直没有大的变化,通过K8S考试的方法就是在模拟环境上反复练习,通过练习熟悉考试环境和考试过程中可能遇到的坑。这里姚远老师详细向大家介绍一下考试的环境和题目,需要详细资料的同学请在文…...
docker清理
1. 查看docker 磁盘占用 docker system df 2. 参考: Docker磁盘占用与清理问题_docker system prune_蓝鲸123的博客-CSDN博客...
rknn优化教程(二)
文章目录 1. 前述2. 三方库的封装2.1 xrepo中的库2.2 xrepo之外的库2.2.1 opencv2.2.2 rknnrt2.2.3 spdlog 3. rknn_engine库 1. 前述 OK,开始写第二篇的内容了。这篇博客主要能写一下: 如何给一些三方库按照xmake方式进行封装,供调用如何按…...
React hook之useRef
React useRef 详解 useRef 是 React 提供的一个 Hook,用于在函数组件中创建可变的引用对象。它在 React 开发中有多种重要用途,下面我将全面详细地介绍它的特性和用法。 基本概念 1. 创建 ref const refContainer useRef(initialValue);initialValu…...
在HarmonyOS ArkTS ArkUI-X 5.0及以上版本中,手势开发全攻略:
在 HarmonyOS 应用开发中,手势交互是连接用户与设备的核心纽带。ArkTS 框架提供了丰富的手势处理能力,既支持点击、长按、拖拽等基础单一手势的精细控制,也能通过多种绑定策略解决父子组件的手势竞争问题。本文将结合官方开发文档,…...
解决Ubuntu22.04 VMware失败的问题 ubuntu入门之二十八
现象1 打开VMware失败 Ubuntu升级之后打开VMware上报需要安装vmmon和vmnet,点击确认后如下提示 最终上报fail 解决方法 内核升级导致,需要在新内核下重新下载编译安装 查看版本 $ vmware -v VMware Workstation 17.5.1 build-23298084$ lsb_release…...
Java - Mysql数据类型对应
Mysql数据类型java数据类型备注整型INT/INTEGERint / java.lang.Integer–BIGINTlong/java.lang.Long–––浮点型FLOATfloat/java.lang.FloatDOUBLEdouble/java.lang.Double–DECIMAL/NUMERICjava.math.BigDecimal字符串型CHARjava.lang.String固定长度字符串VARCHARjava.lang…...
【配置 YOLOX 用于按目录分类的图片数据集】
现在的图标点选越来越多,如何一步解决,采用 YOLOX 目标检测模式则可以轻松解决 要在 YOLOX 中使用按目录分类的图片数据集(每个目录代表一个类别,目录下是该类别的所有图片),你需要进行以下配置步骤&#x…...
WordPress插件:AI多语言写作与智能配图、免费AI模型、SEO文章生成
厌倦手动写WordPress文章?AI自动生成,效率提升10倍! 支持多语言、自动配图、定时发布,让内容创作更轻松! AI内容生成 → 不想每天写文章?AI一键生成高质量内容!多语言支持 → 跨境电商必备&am…...
是否存在路径(FIFOBB算法)
题目描述 一个具有 n 个顶点e条边的无向图,该图顶点的编号依次为0到n-1且不存在顶点与自身相连的边。请使用FIFOBB算法编写程序,确定是否存在从顶点 source到顶点 destination的路径。 输入 第一行两个整数,分别表示n 和 e 的值(1…...
【Nginx】使用 Nginx+Lua 实现基于 IP 的访问频率限制
使用 NginxLua 实现基于 IP 的访问频率限制 在高并发场景下,限制某个 IP 的访问频率是非常重要的,可以有效防止恶意攻击或错误配置导致的服务宕机。以下是一个详细的实现方案,使用 Nginx 和 Lua 脚本结合 Redis 来实现基于 IP 的访问频率限制…...
go 里面的指针
指针 在 Go 中,指针(pointer)是一个变量的内存地址,就像 C 语言那样: a : 10 p : &a // p 是一个指向 a 的指针 fmt.Println(*p) // 输出 10,通过指针解引用• &a 表示获取变量 a 的地址 p 表示…...
