【QT5-自我学习-线程qThread练习-两种使用方式-1:通过继承线程类来使用-基础样例】

【QT5-自我学习-线程qThread练习-两种使用方式-1:通过继承线程类来使用-基础样例】

  • 1、前言
  • 2、实验环境
  • 3-1、学习链接-参考文章
  • 3-2、先前了解-自我总结
      • (1)线程处理逻辑事件,不能带有主窗口的事件
      • (2)一般考虑使用的时候,是当你发现,主窗口会有卡顿,需要线程在后台来处理。
      • (3)通过继承线程类这种方式,自己觉得在使用时,主要注意两点。
  • 4、实验过程
    • (0)实验目标
    • (1)新建工程
    • (2)UI布局
    • (3)线程类代码编写
    • (4)编写mainwindow.cpp内容。
  • 5-1、实际效果
  • 5-2、代码链接
  • 6、细节部分
      • (1)main.cpp加入一段声明代码。
      • (2)拉姆达表达式
  • 7、总结

1、前言

学习线程其实有一段时间了,当时只是学习,没有实际用起来,最近做的一个qt程序,发现如果不使用线程,那么就会导致界面卡死,这样才体现出线程的实际作用。

发现卡顿的程序就是前几天说到的“【QT调用ST-link-使用QT编写程序-调用ST-LINK_CLI.exe-烧写STM32F4xxx-基础样例】”程序。
在融合的时候,发现如果不适用线程,并且下载程序很大的时候,就会直接卡住,虽然等下完后,界面就好了,但是这绝对不是我们想要的。于是融合了线程,发现能够解决这一问题,同时也对线程有了熟悉。

2、实验环境

实验环境还是挺重要的,因为有时候,在你电脑上能运行的东西,在别人的电脑就不一定能运行,这一部分的原因就可能是实验版本不一样。
系统环境:window环境
QT软件版本:qt 5.14.2
ST-Link命令行工具的版本号:STM32 ST-LINK CLI v3.6.0.0
硬件开发板:STM32F407ZET6(正点原子:探索者)
下载器:ST-link
在这里插入图片描述

3-1、学习链接-参考文章

自己也是参考他人文章,通过学习他人的文章与视频学习了qt多线程,当然要说明出处。
如下是博客地址,里面相关概念总结:https://subingwen.cn/qt/thread/
在这里插入图片描述
如下是B站上视频,也是通过视频,敲的代码:https://www.bilibili.com/video/BV1iN411f7dY/?spm_id_from=333.337.search-card.all.click&vd_source=631b10b31b63df323bac39281ed4aff3
在这里插入图片描述

3-2、先前了解-自我总结

博客文章说得已经非常好了,自己也会重新总结下。

(1)线程处理逻辑事件,不能带有主窗口的事件

线程可以在后台辅助你,对一些数据进行除了,但是对于主界面的控件等,不能直接控制,从使用来说,
以下是一个例子,不能直接使用以下方式来调用界面的控件。

ui->label->setText("data");

当然是可以通过一些信号与槽,或者全局变量的方式来传递。

(2)一般考虑使用的时候,是当你发现,主窗口会有卡顿,需要线程在后台来处理。

我自己本次使用的时候,是因为碰到st-link烧写,并且文件很大的时候,主界面会直接卡住,才考虑使用,而不要是为了使用而使用,当你觉得主界面太卡,并且可以放在后台执行的时候,那么你就可以开一个线程。

(3)通过继承线程类这种方式,自己觉得在使用时,主要注意两点。

1、连接号信号与槽
2、编写run函数内容
我们很多时候,是先学习怎么去做,然后返回来在具体了解内部细节的。

4、实验过程

(0)实验目标

采用两种不同速度排序的方式,对一个乱序的数组进行排序,这个过程中,需要生产乱序数组,使用一个线程,两种排序需要使用两个线程,所有一种有3个线程。

(1)新建工程

新建工程,是qtk开始的步骤,至少先让你的空白模块跑起来,如下,这里就不过多叙述了。
在这里插入图片描述

(2)UI布局

我们需要是三个框,也就是listWidget,分别放置三个数组,一个是乱序数组,另外两个是冒泡排序和快排,如下。
在这里插入图片描述

(3)线程类代码编写

虽然自己是看着他人资料,但是不想完全安装他人的,给自己增加些难度,分成了3个文件。
(1)添加新的文件,在项目上右键,然后选择“Add New…”
在这里插入图片描述

(2)添加新的C++文件,然后命名,
在这里插入图片描述

(3)这里可以先不选任何include,随后我们手头添加即可
在这里插入图片描述

(4)编写对于”mythread.h“和“mythread.cpp”内容。
我们需要继承线程类,编写功能函数声明,run函数声明的,如下代码快,

#ifndef MYTHREAD_H
#define MYTHREAD_H

#include <QThread>

class myThread_rand : public QThread
{
    Q_OBJECT
public:
    explicit myThread_rand(QObject *parent = nullptr);
    void recvNum(int num);
protected:
    void run() override;

signals:
    void sendArray(QVector<int> num);
private:
    int m_num;

};

#endif // MYTHREAD_H

“mythread.cpp”内容,主要是实现相应函数内容,这里也直接给出代码块。

#include "mythread.h"
#include <QElapsedTimer>
#include <QDebug>

myThread_rand::myThread_rand(QObject *parent) : QThread(parent)
{

}

void myThread_rand::recvNum(int num)
{
    m_num=num;
}

 void myThread_rand::run()
 {
      qDebug() << "生成随机数的线程地址为:" << QThread::currentThread() << endl;
     QVector<int> list;
     QElapsedTimer time;
     time.start();
     for(int i=0;i<m_num;++i)
     {
         list.push_back(qrand()%10000);
     }
     int milsec = time.elapsed();
     qDebug() << "生成"  << m_num<< "个随机总数用时:"<< milsec <<"毫秒" <<endl;
     emit sendArray(list);
 }

(5)然后就是快派和冒泡的两个部分代码块。重复工作,这里直接截图,具体细节,请看我提供的代码连接。
1、bublesort.h
在这里插入图片描述

2、bublesort.cpp,这里在run中放入排序方式,使用双循环的冒泡,然后放入计时的,就是记录线程的函数。
在这里插入图片描述
3、quicksort.h,快排头文件,一些函数声明等。
在这里插入图片描述
4、quciksort.cpp,快排操作函数,这里库里只有相应函数,我们直接调用就好,就没按照参考文章里,再去实现一遍。
在这里插入图片描述

(4)编写mainwindow.cpp内容。

这里的工作,主要是将各个函数连接起来,并传递数据,因为我们是分文件编写,需要包含,这点请注意,然后按照编好步骤依次编写,这里我自己已经写了步骤,请自己看代码吧。

#include "mainwindow.h"
#include "ui_mainwindow.h"
#include "mythread.h"
#include "bubblesort.h"
#include "quicksort.h"


MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    //1.创建子线程对象
    myThread_rand* gen=new myThread_rand;
    bubblesort_thread* bubble=new  bubblesort_thread;
    quickSort_thread* quick=new quickSort_thread;

    //链接
    connect(this,&MainWindow::starting,gen,&myThread_rand::recvNum);
    //2、启动gen(产生随机数据)子线程+lambda表达式
    connect(ui->pushButton,&QPushButton::clicked,this,[=](){
        //发送信号
        emit starting(10000);
        //启动线程
        gen->start();
    });


     //链接
    connect(gen,&myThread_rand::sendArray,bubble,&bubblesort_thread::recvArray);
     connect(gen,&myThread_rand::sendArray,quick,&quickSort_thread::recvArray);

    //3、启动(排序和快排)子线程发送的数据+ 随机数显示
    connect(gen,&myThread_rand::sendArray,this,[=](QVector<int> list){
        bubble->start();
        quick->start();
       for(int i=0;i<list.size();++i)
       {
           ui->listWidget_randList->addItem(QString::number(list.at(i)));
       }
    });


    //4、(冒泡线程)接收子线程发送的数据+(冒泡)排序后显示
    connect(bubble,&bubblesort_thread::finish,this,[=](QVector<int> list){
       for(int i=0;i<list.size();++i)
       {
           ui->listWidget_bubuleList->addItem(QString::number(list.at(i)));
       }
    });

    //4、(快排线程)接收子线程发送的数据+(快排)排序后显示
    connect(quick,&quickSort_thread::finish,this,[=](QVector<int> list){
       for(int i=0;i<list.size();++i)
       {
           ui->listWidget_quickList->addItem(QString::number(list.at(i)));
       }
    });


}

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


5-1、实际效果

实际效果如下,还是可以看到,不同算法,排序实际确实不是一样的。
在这里插入图片描述

5-2、代码链接

代码链接:https://download.csdn.net/download/qq_22146161/88241687

6、细节部分

(1)main.cpp加入一段声明代码。

根据博主说明,要在main.cpp加入一段声明代码,否则会有错误。
在这里插入图片描述
如下,如果注释掉,就会有问题。
在这里插入图片描述

(2)拉姆达表达式

自己确实不是很深入了解,先学着使用吧,用起来之后,再慢慢理解。
在这里插入图片描述
(3)用于计时线程的类,这个类还是挺方便的,可以帮我们计时,不过使用时,要注意包含,声明等。
在这里插入图片描述

7、总结

一个模块的学习,会成为一块砖,成为你的垫脚石,或者一个建筑的一块砖。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

FairyGUI编辑器的弹窗操作【插件】

之前在FairyGUI编辑器菜单扩展中&#xff0c;我使用了App.Alert("复制失败")来提示操作是否成功。这篇则会说一下我们可以使用的弹窗提示&#xff0c;以及做到类似资源发布成功时的“发布成功”飘窗。 打开APP的API脚本&#xff0c;可以看到有很多公开方法&#xff…

国内ChatGPT对比与最佳方案

很久没写内容了&#xff0c;主要还是工作占据了太多时间。简单分享下我这段时间的研究吧,由于时间仓促&#xff0c;有很多内容没有具体写&#xff0c;请自行到我分享的网站体验查看。 前言 ChatGPT 的出现确实在很大程度上改变了世界。许多人已经亲身体验到了ChatGPT作为一个…

TCP协议报文结构

TCP是什么 TCP&#xff08;传输控制协议&#xff09;是一种面向连接的、可靠的、全双工的传输协议。它使用头部&#xff08;Header&#xff09;和数据&#xff08;Data&#xff09;来组织数据包&#xff0c;确保数据的可靠传输和按序传递。 TCP协议报文结构 下面详细阐述TCP…

「UG/NX」Block UI 截面构建器SectionBuilder

✨博客主页何曾参静谧的博客📌文章专栏「UG/NX」BlockUI集合📚全部专栏「UG/NX」NX二次开发「UG/NX」BlockUI集合「VS」Visual Studio「QT」QT5程序设计「C/C+&#

stm32之14.超声波测距代码

-------------------- 源码 void sr04_init(void) { GPIO_InitTypeDef GPIO_InitStructure; //打开端口B的硬件时钟&#xff0c;就是供电 RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOC,ENABLE); //打开端口E的硬件时钟&#xff0c;就是供电 RC…

java八股文面试[java基础]——Object类有哪些方法

通过IDEA打开Object类就可以看到 &#xff08;1&#xff09;clone方法 保护方法&#xff0c;实现对象的浅复制&#xff0c;只有实现了Cloneable接口才可以调用该方法&#xff0c;否则抛出CloneNotSupportedException异常。 主要是JAVA里除了8种基本类型传参数是值传递&#xf…

Linux配置nginx反向代理

在云服务器上部署高并发的服务&#xff0c;使用Nginx作为反向代理是一种常见的做法&#xff0c;可以实现流量分发、负载均衡&#xff0c;同时提升系统的可靠性和性能。 步骤概览&#xff1a; 安装Nginx&#xff1a; 确保服务器已安装Nginx。若未安装&#xff0c;可使用适用于你…

stm32 无刷电机 V/F控制(无刷电机变频控制)以及与foc(矢量控制)的区别

无刷电机有三种控制方式&#xff0c;方波控制&#xff0c;foc控制以及变频控制&#xff0c;前两章我们讲解了方波和foc的控制方法&#xff0c;今天我们一起来讲一讲什么是无刷电机的变频控制&#xff08;VF&#xff09;以及变频控制的优势是什么。 实验用的硬件还是KY_Motor的无…

Eureka 的几种主动下线服务的方式

补充&#xff1a;在启动eureka服务的时候发现控制台有以下的输出 由此猜想可以通过改接口下线服务&#xff0c; 于是尝试了一下。 果然能从注册中心中移除该实例。 1. 直接停掉服务。 默认情况下&#xff0c;如果Eureka Server在90秒没有收到Eureka客户的续约&#xff0c;它…

AMBA总线协议(9)——AHB(七):终章

一、前言 在之前的文章中我们讲述了AHB协议的分割传输机制&#xff0c;它使得从机可以决定一次传输是否继续进行&#xff0c;以防止 传输的执行将占据大量的时钟周期&#xff0c;有效提高了总线的公平性与效率问题&#xff0c;本文中我们将一次性学习完AHB最后的内容&#xff0…

mysql 8.0 窗口函数 之 分布函数 与 sql server (2017以后支持) 分布函数 一样

mysql 分布函数 percent_rank&#xff08;&#xff09; &#xff1a;等级值 百分比cume_dist() &#xff1a;累积分布值 percent_rank&#xff08;&#xff09; 计算方式 (rank-1)/(rows-1)&#xff0c; 其中 rank 的值为使用RANK()函数产生的序号&#xff0c;rows 的值为当前…

测试框架pytest教程(9)跳过测试skip和xfail

skip无条件跳过 使用装饰器 pytest.mark.skip(reason"no way of currently testing this") def test_example(faker):print("nihao")print(faker.words()) 方法内部调用 满足条件时跳过 def test_example():a1if a>0:pytest.skip("unsupported …

单片机的ADC

如何理解ADC。ADC就是将模拟量转换成数字量的过程&#xff0c;就是转换为计算机所能存储的0和1序列&#xff0c;比如将模拟量转换为一个字节&#xff0c;所以这个字节的大小要能反应模拟量的大小&#xff0c;比如一个0-5V的电压测量量&#xff08;外部输入电压最小0V,最大为5V&…

MyBatis动态SQL、模糊查询与结果映射

目录 前言 一、MyBatis动态SQL 1.动态SQL是什么 2.动态SQL的作用 3.常用动态SQL元素 1. where if 元素 2. set if 元素 3. choose when otherwise 元素 4. 自定义 trim 元素 <1>. 自定义 trim 元素改写上面的 where if 语句 <2>. 自定义 trim 元素改…

2023前端求职经历回顾及面试题总结

文章目录 前言一、求职经历二、前端面经1. 投简历的正确打开方式2. 面经及面试题复盘外企面经、面试题大厂面经、面试题面试中的笔试有三种笔试题 给同行的温馨提示我的其他热门文章 前言 2023 年的春节之前&#xff0c;几乎没有公司招人&#xff0c;直到 2023年2月10日 左右&a…

【ARM AMBA AXI 入门 10 - AXI 总线 DATA信号与 STRB 信号之间的关系 】

文章目录 AXI STRB 信号 AXI STRB 信号 AXI总线是ARM公司设计的高性能处理器接口&#xff0c;其中STRB和DATA信号在AXI协议中有特殊的含义和关系。 DATA信号&#xff1a;在AXI中&#xff0c;DATA信号用于在读写操作中传输实际的数据。数据的大小可以根据AXI接口的位宽来变化&…

【深度强化学习】Python:OpenAI Gym-CarRacing 自动驾驶 | 提供项目完整代码 | 车道检测功能 | 路径训练功能 | 车辆控制功能

💭 写在前面:本篇是关于 OpenAI Gym-CarRacing 自动驾驶项目的博客,面向掌握 Python 并有一定的深度强化学习基础的读者。GYM-Box2D CarRacing 是一种在 OpenAI Gym 平台上开发和比较强化学习算法的模拟环境。它是流行的 Box2D 物理引擎的一个版本,经过修改以支持模拟汽车…

线性代数强化第三章

目录 一&#xff0c;关于A伴随&#xff0c;A逆与初等矩阵 二&#xff0c;分块矩阵 三&#xff0c;矩阵方程 ​ 一&#xff0c;关于A伴随&#xff0c;A逆与初等矩阵 如何证明行列式的值不能是0&#xff1b; 此秩为1. 法一&#xff1a; 法二&#xff1a; 不用看是列变换还是行变…

xargs 的用法 在1个文件夹中批量删除文件,这些删除的文件名是另一个文件夹中的文件名。

xargs 的用法 在1个文件夹中批量删除文件&#xff0c;这些删除的文件名是另一个文件夹中的文件名。 1、问题背景 应用场景 1、问题背景 应用场景 在二进制部署docker时&#xff0c;会把docker的所有可执行文件复制到/usr/bin下。 如果说复制过去后&#xff0c;想要反悔&#x…

vue 学习笔记 简单实验

1.代码(html) <script src"https://unpkg.com/vuenext" rel"external nofollow" ></script> <div id"counter">Counter: {{ counter }} </div> <script> const Counter {data() {return {counter: 5}} } Vue.cr…