【qt创建线程两种方式】

news2024/11/29 4:37:30

QT使用线程的两种方式

1.案例进度条

案例解析:
如图由组件一个进度条和三个按钮组成,当点击开始的时候进度条由0%到100%,点击暂停,进度条保持之前进度,再次点击暂停变为继续,点击停止按钮进度条停止。
案例流程:
1.创建qwidget工程
2.添加四个控件,转到槽函数

在这里插入图片描述

2.使用线程方式一

2.1创建一个类继承QThread,重写run方法

2.2mythread.cpp

#include "mythread.h"
#include <QDebug>
MyThread::MyThread()
{

}
void MyThread::stop()
{
    running=false;
}
//暂停继续
void MyThread::threadStop(bool flag)
{
    pause=flag;
}
//重写run方法
void MyThread::run()
{
    qDebug()<<"线程id:"<<currentThreadId();
    while (1) {
       //触发信号
        while(running){
            while (pause) {
                msleep(100);
            }
            if(value>100)
                value=0;
            emit valChage(value++);
            msleep(100);
        }
        exit(0);
    }
}

2.3mythread.h

#ifndef MYTHREAD_H
#define MYTHREAD_H
#include <QThread>
#include <QDebug>
//继承QThread重写run方法
class MyThread : public QThread
{
    Q_OBJECT
public slots:
    void stop();
    void threadStop(bool flag);
signals:
    void valChage(int);
public:
    MyThread();
    void run();
private:
    int value=0;
    bool running=true;
    bool pause=false;
};

#endif // MYTHREAD_H

2.4widget.h

#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>
#include <QProgressBar>
#include<QThread>
#include "mythread.h"
namespace Ui {
class Widget;
}

class Widget : public QWidget
{
    Q_OBJECT

public:
    explicit Widget(QWidget *parent = 0);
    ~Widget();
signals:

    void stop();
    void threadStop(bool);
private slots:
    void on_pushButton_clicked();

    void on_pushButton_3_clicked();

    void on_pushButton_2_clicked();

private:
    Ui::Widget *ui;
    MyThread *mythread;
};
#endif // WIDGET_H

2.5widget.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()

{
    mythread= new MyThread();
    //绑定信号与槽函数
    connect(mythread,&MyThread::valChage,ui->progressBar,&QProgressBar::setValue);
    //延时
    connect(mythread,&MyThread::finished,mythread, &QObject::deleteLater);
    connect(this,&Widget::stop,mythread,&MyThread::stop);
    connect(this,&Widget::threadStop,mythread,&MyThread::threadStop);
    mythread->start();
    ui->pushButton->setEnabled(false);

}

void Widget::on_pushButton_3_clicked()
{
    emit stop();
}
void Widget::on_pushButton_2_clicked()
{
    static bool flag=true;
    if(flag){
        emit threadStop(true);
        ui->pushButton_2->setText("继续");
        flag=false;
    }else{
        emit threadStop(false);
        ui->pushButton_2->setText("暂停");
        flag=true;
    }
}

3.使用线程方式二

3.1创建类继承QObject

在这里插入图片描述

3.2qworker.h

这里的槽函数实现直接写在.h文件中,不够规范,只便与学习观看,切不要效仿。

#ifndef QWORKER_H
#define QWORKER_H
#include <QObject>
#include <QThread>
#include <QApplication>
class qworker : public QObject
{
    Q_OBJECT
public:
    explicit qworker(QObject *parent = nullptr);

signals:
    void dataChanged(int);
public slots:
    void doWorking(){
        while (!sFlag) {
            if(current>=100)
                current=0;
            while (pFlag) {
               QThread::msleep(10);
               //接收来自外部进程的事件,否则收不到信号
               QApplication::processEvents();
            }
            emit dataChanged(current++);
            QThread::msleep(10);
            QApplication::processEvents();
        }
        sFlag=false;
        current=0;
    }
     void pause(bool flag){
        pFlag=flag;
     }
     void stop(){
         sFlag=true;
     }
private:
    //进度条
    int current=0;
    //暂停
    bool pFlag=false;
    //停止
    bool sFlag=false;
};
#endif // QWORKER_H

3.3widget.h

#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>
//引入qworker.h
#include "qworker.h"

namespace Ui {
class Widget;
}

class Widget : public QWidget
{
    Q_OBJECT

public:
    explicit Widget(QWidget *parent = 0);
    ~Widget();
signals:
    void working();
    void pause(bool);
    void stop();
private slots:
    void on_pushButton_clicked();
    void on_pushButton_2_clicked();
    void on_pushButton_3_clicked();
c
private:
    Ui::Widget *ui;
    qworker *worker;
    QThread thread;
};
#endif // WIDGET_H

3.4widget.cpp

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

Widget::Widget(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::Widget)
{
    ui->setupUi(this);
    worker=new qworker();
    //移动到线程中
    worker->moveToThread(&thread);
    //开始
    connect(this,&Widget::working,worker,&qworker::doWorking);
    //暂停
    connect(this,&Widget::pause,worker,&qworker::pause);
    //停止
    connect(this,&Widget::stop,worker,&qworker::stop);
    connect(worker,&qworker::dataChanged,ui->progressBar,&QProgressBar::setValue);
    thread.start();
}
Widget::~Widget()
{
    delete ui;
}
void Widget::on_pushButton_clicked()
{
    emit working();
}

void Widget::on_pushButton_2_clicked()
{
    static bool flag=true;
    if(flag){
    emit pause(true);
    flag=false;
    ui->pushButton_2->setText("继续");
    }else{
        emit pause(false);
        flag=true;
        ui->pushButton_2->setText("暂停");
    }
}
void Widget::on_pushButton_3_clicked()
{
    emit stop();
}

4.总结

两种方式都可以完成案例需求:

方式一:

1.通过继承QThread类重写run方法

2.重写类MyThread的虚函数void run();,即新建一个函数protected void run(),然后对其进行定义。

3.在需要用到多线程的地方,实例MyThread,然后调用函数MyThread::start()后,则开启一条线程,自动运行函数run()。

4.当停止线程时,调用MyThread::wait()函数,等待线程结束,并且回收线程资源。

方式二:

1.继承QObject类,创建对象。

2.通过moveToThread将派生类对象移动到一个线程中。

3.通过信号连接派生类的槽函数,将耗时的工作放到这个槽函数中运行。

4.用信号QThread::finished绑定槽函数QThread::deleteLatater(),在线程退出时,自动销毁该线程和相关资源。

5.通过QThread的start()函数开启多线程。

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

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

相关文章

如何实现Android平台GB28181设备接入模块按需打开摄像头并回传数据

技术背景 实际上&#xff0c;我在年前的blog&#xff0c;已经写过Android平台GB28181后台service模式启动摄像头按需回传数据了&#xff0c;此次版本&#xff0c;是上个demo的迭代版&#xff0c;目的是平台侧如果不发起回传请求的话&#xff0c;摄像头不打开。 后台service模…

系统调用之文件IO

学习完使用标准io库函数&#xff0c;进一步深入linux的内核实现系统的调用&#xff0c;本节主要学习文件io的相关函数。 标准IO与文件IO的区别 标准io是库函数&#xff0c;是系统调用的封装。 文件io是系统调用&#xff0c;是linux内核中的函数。 标准io有缓存&#xff0c;文件…

云原生之容器编排实践-在K8S集群中使用Registry2搭建私有镜像仓库

背景 基于前面搭建的3节点 Kubernetes 集群&#xff0c;今天我们使用 Registry2 搭建私有镜像仓库&#xff0c;这在镜像安全性以及离线环境下运维等方面具有重要意义。 Note: 由于是测试环境&#xff0c;以下创建了一个 local-storage 的 StorageClass &#xff0c;并使用本地…

STM32 TIM输入捕获测频率占空比库函数

目录 一、输入捕获初始化函数 TIM_ICInit TIM_PWMIConfig TIM_ICStructInit 二、主从触发模式对应函数 TIM_SelectInputTrigger TIM_SelectOutputTrigger TIM_SelectSlaveMode 三、配置分频器函数 TIM_SetIC1Prescaler TIM_SetIC2Prescaler TIM_SetIC3Prescaler T…

OpenAI视频生成模型Sora背后的技术及其深远的影响

前言 Sora的视频生成技术在保真度、长度、稳定性、一致性、分辨率和文字理解等方面都达到了当前最优水平。其核心技术包括使用视觉块编码将不同格式的视频统一编码成Transformer可训练的嵌入向量&#xff0c;以及类似于扩散过程的UNet方法进行降维和升维的加噪与去噪操作。通过…

IO 流分类

一、File File 类&#xff08;磁盘操作&#xff09;可以用于表示文件和目录的信息&#xff0c;但是它不表示文件的内容。递归地列出一个目录下所有文件&#xff1a; public static void listAllFiles(File dir) {if (dir null || !dir.exists()) {return;}if (dir.isFile())…

Java集合篇之深入解析LinkedList

写在开头 作为ArrayList的同门师兄弟&#xff0c;LinkedList的师门地位逊色不少&#xff0c;除了在做算法题的时候我们会用到它之外&#xff0c;在实际的开发工作中我们极少使用它&#xff0c;就连它的创造者都说&#xff1a;“I wrote it&#xff0c;and I never use it”&am…

MySQL之json数据操作

1 MySQL之JSON数据 总所周知&#xff0c;mysql5.7以上提供了一种新的字段格式json&#xff0c;大概是mysql想把非关系型和关系型数据库一口通吃&#xff0c;所以推出了这种非常好用的格式&#xff0c;这样&#xff0c;我们的很多基于mongoDB的业务都可以用mysql去实现了。当然…

Java 基于微信小程序的汽车4S店客户管理系统

博主介绍&#xff1a;✌程序员徐师兄、7年大厂程序员经历。全网粉丝12w、csdn博客专家、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ &#x1f345;文末获取源码联系&#x1f345; &#x1f447;&#x1f3fb; 精彩专栏推荐订阅&#x1f447;…

C++类和对象-多态->案例1计算器类、案例2制作饮品、案例3电脑组装需求分析和电脑组装具体实现

#include<iostream> using namespace std; #include<string> //分别利用普通写法和多态技术实现计算器 //普通写法 class Calculator { public: int getResult(string oper) { if (oper "") { return m_Num1 m_Num2; …

引入成熟的Pytest自动化测试框架

虽然我们能使用脚本编写自动化测试框架&#xff0c;但没有必要重复找车轮子&#xff0c;引入成熟的自动化测试框架即可&#xff0c; Pytest是目前最成熟、功能最全面的Python测试框架之一&#xff0c;简单灵活、易于上手&#xff0c;可完全兼容其他测试框架如unitest&#xff…

普中51单片机学习(十)

动态数码管 数码管显示原理 动态显示的特点是将所有数码管的段选线并联在一起&#xff0c;由位选线控制是哪一位数码管有效。选亮数码管采用动态扫描显示。所谓动态扫描显示即轮流向各位数码管送出字形码和相应的位选&#xff0c;利用发光管的余辉和人眼视觉暂留作用&#xf…

SSTI模板注入漏洞(vulhub 复现)

首先了解模板引擎&#xff1a; 模板引擎&#xff08;这里特指用于Web开发的模板引擎&#xff09;是为了使用户界面与业务数据&#xff08;内容&#xff09;分离而产生的&#xff0c;它可以生成特定格式的文档&#xff0c;利用模板引擎来生成前端的html代码&#xff0c;模板引擎…

OpenAI:Sora视频生成模型技术报告(中文)

概述 视频生成模型作为世界模拟器 我们探索视频数据生成模型的大规模训练。具体来说&#xff0c;我们在可变持续时间、分辨率和宽高比的视频和图像上联合训练文本条件扩散模型。我们利用transformer架构&#xff0c;在视频和图像潜在代码的时空补丁上运行。我们最大的模型Sor…

HCIA-HarmonyOS设备开发认证V2.0-IOT硬件子系统-UART

目录 一、UART 概述二、UART 模块相关API三、UART 接口调用实例四、UART HDF驱动开发4.1、开发步骤(待续...) 坚持就有收获 一、UART 概述 UART 是通用异步收发传输器&#xff08;Universal Asynchronous Receiver/Transmitter&#xff09;的缩写&#xff0c;是通用串行数据总…

Chrome浏览器安装Axure-Chrome-Extension插件

Chrome浏览器打开Axure生成的HTML静态文件页面时&#xff0c;会显示如下图AXURE RP EXTENSION FOR CHROME&#xff0c;这是因为Chrome浏览器没有安装Axure插件Axure-Chrome-Extension导致的。 解决方法&#xff1a; 插件下载地址&#xff1a;https://download.csdn.net/downlo…

CleanMyMacX需要付费吗?多少钱?有哪些新功能

CleanMyMac X是一个付费应用程序**&#xff0c;需要许可证或订阅来解锁所有功能。不过&#xff0c;CleanMyMac X提供免费试用版供您访问其有限的功能。在试用模式下&#xff0c;用户可以使用部分功能进行体验&#xff0c;但这并非完全免费&#xff0c;因为某些功能会受到限制。…

Android下SF合成流程重学习之GPU合成

Android下SF合成流程重学习之GPU合成 引言 SurfaceFlinger中的图层选择GPU合成(CLIENT合成方式)时&#xff0c;会把待合成的图层Layers通过renderengine(SkiaGLRenderEngine)绘制到一块GraphicBuffer中&#xff0c;然后把这块GraphicBuffer图形缓存通过调用setClientTarget传递…

代码随想录算法训练营 DAY20 | 二叉树(7)

一、LeetCode 530 二叉搜索树的最小绝对值 题目链接&#xff1a;530.二叉搜索树的最小绝对值https://leetcode.cn/problems/minimum-absolute-difference-in-bst/ 思路一&#xff1a;利用搜索二叉树的中序遍历结果为有序数组的性质&#xff0c;将遍历结果保存到数组中&#xf…

分析:香港2亿港元诈骗案的风险特征及技术检测思路

目录 深度伪造带来的新挑战 如何有效检测深度伪造&#xff1f; 多管齐下的安全策略 据香港公共广播公司报道&#xff0c;一家跨国公司香港分行的一名员工在一次电话会议后被骗支付了2亿港元&#xff08;超过2500万美元&#xff09;的资金。 据介绍&#xff0c;这起骗局始于202…