QThread(创建线程)

news2025/6/3 23:39:24

在Qt 中QThread 类提供了于平台无关的线程,一个QThread代表一个在应用程序中可以独立控制的线程,可以和进程中的其他线程分享数据。

QThread 对象管理程序中的一个控制线程。QThreads 在 run() 中开始执行。默认情况下,run() 通过调用 exec() 来启动事件循环,并在线程内运行 Qt 事件循环。

QThread中的函数:

exec()

进入事件循环并等待 exit() 被调用,返回传递给exit() 的值。如果通过 quit() 调用 exit(),则返回的值为 0。

此函数旨在从 run() 中调用。必须调用此函数才能启动事件处理

exit()告知线程的事件循环以返回代码退出
currentThread()返回指向管理当前正在执行的线程的 QThread 的指针。
idealThreadCount()返回可在系统上运行的理想线程数,如果无法检测到处理器内核数,则此函数返回 1。
isDone()如果线程完成返回true 否则返回 false
isRunning()如果线程正在运行返回true 否则返回 false
loopLevel()返回线程的当前事件循环级别
msleep()强制当前线程休眠毫秒
sleep()强制当前线程休眠几秒钟,此功能不保证准确性。在重负载条件下,应用程序可能会休眠超过
usleep()强制当前线程休眠 usecs微秒,此功能不保证准确性。在重负载条件下,应用程序可能比 usecs 休眠时间更长
priority()返回正在运行的线程的优先级
isInterruptionRequest()如果应停止在此线程上运行的任务返回true否则返回false
requestInterruption()请求中断线程。该请求是建议性的,由线程上运行的代码决定是否以及如何对此类请求进行操作。此函数不会停止线程上运行的任何事件循环,也不会以任何方式终止它。
run()线程的起点,调用 start() 后,新创建的线程调用此函数,您可以重新实现此函数以促进高级线程管理

wait()

阻塞线程,直到如果线程已完成,此函数将返回 true。如果线程尚未启动,它也返回 true。或到了最后期限。如果达到截止时间,此函数将返回 false
setEventDispatcher()设置线程的事件调度
setPriority()设置线程优先级
setStackSize()设置线程的最大堆栈大小
stackSize()返回线程的最大堆栈大小
yieldCurrentThread()将当前线程的执行生成到另一个可运行的线程

信号:

finished()此信号在完成执行之前从关联的线程发出
started()在调用run() 函数之前,当关联线程开始执行时,此信号从关联线程发出。

槽函数:

quit()告知线程的事件循环退出并返回代码 0(成功)。等效于调用 QThread::exit(0)
start()通过调用 run() 开始执行线程。操作系统将根据优先级参数调度线程。如果线程已在运行,则此函数不执行任何操作
terminate()终止线程的执行。线程可能会也可能不会立即终止,具体取决于操作系统的调度策略。在 terminate() 之后使用 QThread::wait() 可以肯定。

创建一个单独的线程:

创建一个QThread的子类,然后重新实现run()函数,QThread是从run()函数开始执行,在run()函数中需要调用exec()来开启事件循环。

class widget::public QThread
{
    protected:
        void run()override;
}


void widget::run()//重写run函数
{
    QTcpSocket socket;
    socket.connectToHost(hostName,portNumber);
    exec();//开启事件循环
}

在线程中创建一个QTcpSocket,然后执行这个线程的事件循环。

注意:线程中无法使用任何界面部件类

线程中函数的使用:

start()开启线程,start会自动调用run()函数

线程开始、结束、终止会发出 started()、finished()和terminated()

可以使用isFinnished()和isRuning()查询状态,使用wait()来阻塞,直到线程结束执行,每个线程都会从操作系统中获取自己的堆栈,使用setStackSize()可以设置一个自定义的堆栈。

每个线程都可以有自己的事件循环,可以通过调用exec()函数来启动事件循环,可以调用exit()或quit()来停止事件循环 ,

线程中拥有一个事件循环,使得它可以关联其他线程中的信号到本线程的槽上,这使用了队列关联机制,使用connect关联时将Qt::connectionType类型参数指定Qt::QueuedConection

拥有事件循环就可以使用一些需要事件循环的类

使用terminate()函数,可以强制终止一个正在执行的线程,线程是否会立即停止也会受操作系统的调度策略影响,可以在调用完terminate()后调用QThread::wiat()来同步终止,一般来说不会推荐使用该函数,可能会因线程的任意停止而无法进行一些清理操作。

sleep()休眠 n秒、  msleep()休眠n毫秒 、usleep()暂停n微妙

currentThread()和currentThread()可以返回当前执行线程的表示符,前者返沪一个该线程的系统特定的ID;后者返回一个QThread指针 

举一个例子:

点击开启线程按钮,开启线程,点击暂停,线程暂停,且在QLineEdit上显示数据 

创建一个thread类:

thread.h

#ifndef THREAD_H
#define THREAD_H

#include <QObject>
#include<QThread>
class Thread : public QThread
{
    Q_OBJECT
public:
    explicit Thread(QObject *parent = nullptr);

    void stop();//暂停
protected:
    void run() override;
    int i=0;//记录数据
    volatile bool stoped;//存放暂停的条件,使用volatile 使得该值可以获取最新值

signals:

};

#endif // THREAD_H

thread.cpp

#include "thread.h"
#include<QWidget>
#include<QDebug>
Thread::Thread(QObject *parent) : QThread(parent)
{
    stoped=true;

}
void Thread::run()
{
    while(stoped)
    {
        qDebug()<<QString("数字为:%1").arg(i);
        msleep(1000);//暂停一秒
        i++;
    }
    stoped=true;
}
void Thread::stop()
{
    stoped=false;
}

主窗口:widget

ui界面中添加以下空间并转到槽

widget.h 

#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>
#include "thread.h"
#include<QDebug>
QT_BEGIN_NAMESPACE
namespace Ui { class Widget; }
QT_END_NAMESPACE

class Widget : public QWidget
{
    Q_OBJECT

public:
    Widget(QWidget *parent = nullptr);
    ~Widget();


private slots:
    void on_pushButton_clicked();

    void on_pushButton_2_clicked();

private:
    Ui::Widget *ui;
    Thread th;
};
#endif // WIDGET_H

widget.cpp

 

#include "widget.h"
#include "ui_widget.h"

Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);
}

Widget::~Widget()
{
    delete ui;
}

void Widget::on_pushButton_clicked()//开启线程
{
    th.start();//开启线程
    qDebug()<<"线程已开启";
    ui->pushButton->setEnabled(false);
    ui->pushButton_2->setEnabled(true);
}

void Widget::on_pushButton_2_clicked()//暂停
{
    if(th.isRunning())
    {
        th.stop();//暂停
        qDebug()<<"线程已暂停";
        ui->pushButton->setEnabled(true);
        ui->pushButton_2->setEnabled(false);
    }

}

运行效果:

点击开启

 

 点击暂停:

使用QObject::moveToThread()函数来创建线程,将工作器对象移动到线程来使用工作器对象。

 

参考文献:

Q阅读类|Qt核心 5.15.12

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

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

相关文章

C语言进阶——自定义类型:结构体

&#x1f307;个人主页&#xff1a;_麦麦_ &#x1f4da;今日名言&#xff1a;生活不可能像你想象的那么好&#xff0c;也不会像你想象的那么糟。——莫泊桑《羊脂球》 目录 一、前言 二、正文 1结构体 1.1结构体的基础知识 1.2结构的声明 1.3特殊的声明 1.4结构体变量的…

若依框架---数据转树状层级

&#x1f44f;作者简介&#xff1a;大家好&#xff0c;我是小童&#xff0c;Java开发工程师&#xff0c;CSDN博客博主&#xff0c;Java领域新星创作者 &#x1f4d5;系列专栏&#xff1a;前端、Java、Java中间件大全、微信小程序、微信支付、若依框架、Spring全家桶 &#x1f4…

Node=>Express路由 学习2

1.概念 Express路由指的是客户端的请求与服务器处理函数之间的映射关系 Express路由由三部分组成 请求类型 请求URL地址 处理函数 app.METHOD ( PATH , HANDLER )根据定义的先后顺序进行匹配 请求类型和请求的URl同时匹配成功才会调用相应的处理函数 简单用法 2.模块化路由 为了…

《里奥哈酒友记》 | 里奥哈的历史—品鉴瑞格尔侯爵葡萄酒

2022年末&#xff0c;里奥哈大使组合怪怪和思羽完成了里奥哈线上活动两大“壮举”&#xff0c;10期《里奥哈酒友记》系列视频和40集《美酒之乡——里奥哈》有声专辑&#xff0c;吸引了许多葡萄酒资深爱好者的目光&#xff0c;也成功地让更多的人了解到里奥哈。由里奥哈推广大使…

粘包拆包问题

什么是粘包/拆包 TCP是个“流”式的协议&#xff0c;会根据TCP缓冲区的实际情况进行包的划分。在业务层面认为一个完整的包&#xff0c;可能会被TCP拆分成多个小包进行发送&#xff0c;也可能把多个小的包封装成一个大的数据包进行发送 粘包拆包问题解决方法 由于TCP协议底层…

电脑分盘怎么分?分盘详细教程来了,图文教学

电脑作为小伙伴日常生活使用的工具&#xff0c;很多事情都需要使用电脑来进行处理。虽然小伙伴使用电脑比较多&#xff0c;但是还是有不少的小伙伴不知道电脑分盘怎么分&#xff1f;其实电脑分盘很简单&#xff0c;下面小编就以图文教学的方式&#xff0c;详细的向小伙伴介绍电…

Python:迷宫

题目描述 本题为填空题&#xff0c;只需要算出结果后&#xff0c;在代码中使用输出语句将所填结果输出即可。 X 星球的一处迷宫游乐场建在某个小山坡上。它是由 1010 相互连通的小房间组成的。 房间的地板上写着一个很大的字母。我们假设玩家是面朝上坡的方向站立&#xff0…

【Linux系统编程】01:命令行解析

命令行解析 1.getopt调用介绍 头文件&#xff1a;<unistd.h> 原型&#xff1a;int getopt(int argc, char * const argv[], const char *optstring); argc、argv&#xff1a;由main函数的参数直接传递而来optstring&#xff1a;一个包含所有合法可选字符组成的字符串 …

超高精度PID调节器的特殊功能(3)——变送输出(转发)功能及其应用

摘要&#xff1a;变送输出是高级PID控制器的一项重要扩展功能&#xff0c;可用于多区控制、串级控制、比值控制和差值控制以及数据采集及记录。为展示变送输出功能的强大作用&#xff0c;本文主要针对超高精度VPC 2021系列PID控制器&#xff0c;介绍了变送输出的具体功能、参数…

【FPGA】Verilog:组合电路 | 3—8译码器 | 编码器 | 74LS148

前言&#xff1a;本章内容主要是演示Vivado下利用Verilog语言进行电路设计、仿真、综合和下载 示例&#xff1a;编码/译码器的应用 ​ 功能特性&#xff1a; 采用 Xilinx Artix-7 XC7A35T芯片 配置方式&#xff1a;USB-JTAG/SPI Flash 高达100MHz 的内部时钟速度 存储器&…

部门新来了个软件测试工程师,看着一副毛头小子的样儿,哪想到是新一代卷王...

内卷&#xff0c;是现在热度非常高的一个词汇&#xff0c;随着热度不断攀升&#xff0c;隐隐到了“万物皆可卷”的程度。 在程序员职场上&#xff0c;什么样的人最让人反感呢? 是技术不好的人吗?并不是。技术不好的同事&#xff0c;我们可以帮他。 是技术太强的人吗?也不…

【精彩点评】正确理解区块链能源消耗的内涵以及对绿色区块链的探索

发表时间&#xff1a;2022年4月13日 信息来源&#xff1a;bsvblockchain.org 为了理解区块链技术的工作原理并确定如何更好地对其加以利用&#xff0c;就区块链技术提出疑问是不可避免的。也许你正在被区块链的能源效率这个问题所困扰。 经常有人说&#xff0c;一些区块链网络…

Spring MVC 之获取参数(对象、JSON格式数据、URL地址参数、文件、Cookie)

文章目录1. 获取单个参数2. 获取多个参数3. 获取对象4. 后端参数重命名 RequestParam5. 接收 JSON 格式的数据 RequestBody6. 从 URL 地址中获取参数 PathVariable7. 上传文件 RequestPart8. 获取Cookie (CookieValue)/Session/header8.1 获取 Request 和 Response 对象8.2 获取…

【GD32F427开发板试用】SysTick定时器的ms中断,us计时

本篇文章来自极术社区与兆易创新组织的GD32F427开发板评测活动&#xff0c;更多开发板试用活动请关注极术社区网站。作者&#xff1a;远小刘 1、系统滴答定时器 参考资料《Cortex M3与M4权威指南.pdf》中的9.5 The SysTick timer小节&#xff0c;里面详细讲解了 1、为什么要用…

一分钟教会使用ChatGPT,保姆级ChatGPT教程

最近ChatGPT大火&#xff01;微软退出首款ChatGPT搜索引擎&#xff0c;阿里等国内巨头也纷纷爆出自家产品&#xff0c;一夜之间&#xff0c;全球最大的科技公司仿佛都回到了自己年轻时的样子&#xff01; 然而&#xff0c;ChatGPT这么火&#xff0c;这么好玩的东西&#xff0c…

Knowledgeowl VS Baklib:你需要知道的一切!

KnowledgeOwl 和 Baklib都是知识库软件的示例。您可以使用每个平台为用户创建自己的知识库和托管文档。每个平台都允许您从同一帐户创建多个知识库&#xff0c;并且可以为用户提供内部和外部知识库。什么是知识库&#xff1f;知识库是一个集中的信息存储库&#xff0c;旨在为无…

Koa2-项目中的基本应用

文章目录安装配置koa2配置nodemon,热更新我们的项目中间件什么是中间件&#x1f47b;洋葱模型路由中间件连接数据库 - mysql后端允许跨域处理请求getpostputdelete后续会继续更新安装配置koa2 &#x1f47b;安装 koa2 npm i koa2 -s&#x1f47b;在package.json 配置,当然是在…

用LCR测试仪测试无线充电系统中的线圈

宽阻抗范围用来表征电感和质量因数– 高精度 DCR 测量– 制造环节快速测量– 大量夹具可供选择智能终端上不断增加新功能&#xff0c;电池寿命成为用户最头痛的问题之一。相比便携式电源和电缆供电而言&#xff0c;无线充电技术因其方便性和多功能性获得了很大的关注&#xff0…

MySQL —— 表的增删查改(一)

目录 表的增删查改&#xff08;一&#xff09; 一、create 1. 单行数据全列插入 2. 多行数据指定列插入 3. 插入否则更新 4. 替换 二、Retrieve 1. select列 1. 全列查询 2. 指定列查询 3. 查询字段为表达式 4. 为查询结果指定别名 5. 结果去重 2. where条件 1…

辞旧岁立新年 | 展望前端工程师的2023

「InfoQ 年度技术盘点与展望」是由InfoQ主办的年度技术盘点与展望项目&#xff0c;是 InfoQ 全年最重要的内容选题之一。 近日&#xff0c;字节跳动云原生 PaaS 资深前端工程师黄健受邀参与&#xff0c;分享主题为 《展望前端研发工程师的 2023》 。本文整理自黄健于直播中分享…