Qt编程技巧总结篇(3)-信号-槽-多线程(二)

文章目录

  • Qt编程技巧总结篇(3)-信号-槽-多线程(二)
    • 主进程与子线程
    • 线程同步
    • 实例与应用
  • 小结

Qt编程技巧总结篇(3)-信号-槽-多线程(二)

  多线程学习,使用QMutex,好了,开整~

主进程与子线程

主进程:经常处于空闲状态,仅处理短小精悍、不怎么占用时间的“小”函数。
子线程:处理主要的计算啊!存储啊!循环等复杂费时的任务。

线程同步

线程同步:子线程中运算量较大的函数在执行的过程中不希望被主线程调用,放置该函数的中断, 因而这类函数需要被保护起来,令其在执行过程中不能被其他线程打断,以保证计算机结果的完整性。
线程同步可以使用:QMutex,QMutexLocker,QReadWriteLock,QReadLocker, QWriteLocker,QWaitCondition,QSemaphore.
这里的例子主要是:QMutexQMutexLocker的应用。

实例与应用

下面的例子是《 QT5.9 c++ 开发指南》中的例子,代码放这里,欢迎参考学习!

子线程.hqdicethread.h文件,

#ifndef QDICETHREAD_H
#define QDICETHREAD_H#include <QObject>
#include <QThread>
#include <QMutex>
#include <QMutexLocker>
#include <QTime>class QDiceThread : public QThread
{Q_OBJECT
public:QDiceThread();void diceBegin();                        // 投色子void diceEnd();                          // 读色子void stopThread();                       // 停止线程bool readVal(int *seq,int *diceValue);   // 主线程读色子private:QMutex mutex; //互斥量int m_seq = 0;int m_diceVal;bool m_pause = true;bool m_stop=false;protected:void run() Q_DECL_OVERRIDE;
};#endif // QDICETHREAD_H

子线程.hqdicethread.cpp 文件,

#include "qdicethread.h"QDiceThread::QDiceThread()
{}void QDiceThread::diceBegin()
{m_pause = false;
}void QDiceThread::diceEnd()
{m_pause = true;
}void QDiceThread::stopThread()
{m_stop = true;
}bool QDiceThread::readVal(int *seq, int *diceValue)
{if(mutex.tryLock())     //试图锁定一个互斥量,成功返回true。{*seq = m_seq;*diceValue = m_diceVal;mutex.unlock();return true;}else{return false;}
}void QDiceThread::run()
{m_stop = false;m_seq = 0;qsrand(QTime::currentTime().msec()); // 随机数初始化,qsrand是线程安全的while(!m_stop){/* mutex.lock() 与 mutex.unlock() 配对使用 */
//        if(!m_pause)
//        {
//            mutex.lock();           //锁定互斥量,他将阻塞执行直到其他线程解锁这个互斥量
//            m_diceVal = qrand();
//            m_diceVal = (m_diceVal%6)+1;
//            m_seq++;
//            mutex.unlock();         // 解锁互斥量
//        }/* 在一些逻辑复杂的代码中,上述方法配对容易出错,可采用QMutexLocker的方法进行简化 */if(!m_pause){QMutexLocker Locker(&mutex);m_diceVal = qrand();m_diceVal = (m_diceVal%6)+1;m_seq++;}msleep(100); // 休眠100ms}
}

主线程.h :dialog.h文件,

#ifndef DIALOG_H
#define DIALOG_H#include <QDebug>
#include <QDialog>
#include <QTimer>
#include "qdicethread.h"QT_BEGIN_NAMESPACE
namespace Ui { class Dialog; }class Dialog : public QDialog
{Q_OBJECT// 需要写在前面
private:int mSeq,mDiceValue;QDiceThread   threadA;QTimer  mTimer;//定时器public:Dialog(QWidget *parent = nullptr);~Dialog();private slots:void onthreadA_started();void onthreadA_finished();void onTimeOut(); //定时器处理槽函数????void on_btnStartThread_clicked();void on_btnDiceBegin_clicked();void on_btnDiceEnd_clicked();void on_btnStopThread_clicked();void on_btnClear_clicked();private:Ui::Dialog *ui;protected:void closeEvent(QCloseEvent *evet);};
#endif // DIALOG_H

主线程.cpp :dialog.cpp文件,

  • 连接槽函数与信号函数
#include "dialog.h"
#include "ui_dialog.h"Dialog::Dialog(QWidget *parent): QDialog(parent), ui(new Ui::Dialog)
{ui->setupUi(this);connect(&threadA,SIGNAL(started()),this,SLOT(onthreadA_started()));connect(&threadA,SIGNAL(finished()),this,SLOT(onthreadA_finished()));connect(&mTimer,SIGNAL(timeout()),this,SLOT(onTimeOut()));}Dialog::~Dialog()
{delete ui;
}void Dialog::onthreadA_started()
{ui->LabA->setText("Thread 状态:thread started.");
}void Dialog::onthreadA_finished()
{ui->LabA->setText("Thread 状态:thread finished.");
}void Dialog::onTimeOut()
{int tmpSeq=0,tmpValue=0;bool valid = threadA.readVal(&tmpSeq, &tmpValue);if(valid && (tmpSeq != mSeq)) // 获取的是有效且新的数据{qDebug()<<tmpSeq;mSeq = tmpSeq;mDiceValue = tmpValue;QString str=QString::asprintf("第 %d 次投掷点数为:%d",mSeq,mDiceValue);ui->plainTextEdit->appendPlainText(str);QPixmap pic;QString fileName = QString::asprintf(":/dice/images/d%d.jpg",mDiceValue);pic.load(fileName);ui->LabPic->setPixmap(pic);}
}void Dialog::on_btnStartThread_clicked()
{mSeq = 0;threadA.start();ui->btnStartThread->setEnabled(false);ui->btnStopThread->setEnabled(true);ui->btnDiceBegin->setEnabled(true);ui->btnDiceEnd->setEnabled(false);
}void Dialog::on_btnDiceBegin_clicked()
{threadA.diceBegin();mTimer.start(100); //定时器100ms读一次数据ui->btnDiceBegin->setEnabled(false);ui->btnDiceEnd->setEnabled(true);
}void Dialog::on_btnDiceEnd_clicked()
{threadA.diceEnd();mTimer.stop(); // 暂停定时器ui->btnDiceBegin->setEnabled(true);ui->btnDiceEnd->setEnabled(false);
}void Dialog::on_btnStopThread_clicked()
{threadA.stopThread();threadA.wait();ui->btnStartThread->setEnabled(true);ui->btnStopThread->setEnabled(false);ui->btnDiceBegin->setEnabled(false);ui->btnDiceEnd->setEnabled(false);
}void Dialog::on_btnClear_clicked()
{ui->plainTextEdit->clear();
}void Dialog::closeEvent(QCloseEvent *evet)
{if(threadA.isRunning()){threadA.stopThread();threadA.wait();}evet->accept();
}

主函数main.cpp文件,

#include "dialog.h"#include <QApplication>int main(int argc, char *argv[])
{QApplication a(argc, argv);Dialog w;w.show();return a.exec();
}

小结

  学习,加油,共勉。

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

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

相关文章

RTK_ROS_导航(3):点云的压缩,PointCloud转scan

目录 1. 源码的安装2. 修改订阅的话题3. 可视化1. 源码的安装 安装过程如下 mkdir -p point_to_scan_ws/src cd point_to_scan_ws/src git clone https://github.com/BluewhaleRobot/pointcloud_to_laserscan.git cd .. catkin_make source devel/setup.bash2. 修改订阅的话题 …

2024.07.01校招 实习 内推 面经

绿*泡*泡VX&#xff1a; neituijunsir 交流*裙 &#xff0c;内推/实习/校招汇总表格 1、校招 | 元戎启行2025校园招聘正式批正式启动&#xff08;内推&#xff09; 校招 | 元戎启行2025校园招聘正式批正式启动&#xff08;内推&#xff09; 2、提前批 | 多益网络2025届校园…

基于抽象 HandlerInterceptor 快速实现接口鉴权

欢迎关注公众号&#xff1a;冬瓜白 相关文章&#xff1a; 每天学习一点点之 Spring Web MVC 之抽象 HandlerInterceptor 快速实现常用功能&#xff08;限流、权限等&#xff09; 在[每天学习一点点之 Spring Web MVC 之抽象 HandlerInterceptor 快速实现常用功能&#xff08…

Numpy的广播机制(用于自动处理不同形状的数组)

NumPy 广播是一种强大的机制&#xff0c;允许 NumPy 在执行元素级运算时自动处理不同形状的数组。广播的规则使得无需显式地创建匹配形状的数组&#xff0c;直接进行运算&#xff0c;大大简化了代码并提高了效率。 基本概念 广播的基本思想是让较小的数组在需要的维度上进行扩…

【MySQL数据库之概念性问题】

1、关系型数据库和非关系型数据库 关系型数据库&#xff08;Relational Database&#xff0c;简称RDBMS&#xff09;和非关系型数据库&#xff08;NoSQL Database&#xff09;是两种不同的数据库类型。SQL本身叫做结构化查询语言1、关系型数据库&#xff1a;&#xff08;MySQL…

Django 更新数据 save()方法

1&#xff0c;添加模型 Test/app11/models.py from django.db import modelsclass Post(models.Model):title models.CharField(max_length200)content models.TextField()pub_date models.DateTimeField(date published)class Book(models.Model):title models.CharFie…

Spring Boot集成grpc快速入门demo

1.什么是GRPC&#xff1f; gRPC 是一个高性能、开源、通用的RPC框架&#xff0c;由Google推出&#xff0c;基于HTTP2协议标准设计开发&#xff0c;默认采用Protocol Buffers数据序列化协议&#xff0c;支持多种开发语言。gRPC提供了一种简单的方法来精确的定义服务&#xff0c…

UE5.3-基础蓝图类整理一

常用蓝图类整理&#xff1a; 1、获取当前关卡名&#xff1a;Get Current LevelName 2、通过关卡名打开关卡&#xff1a;Open Level(by name) 3、碰撞检测事件&#xff1a;Event ActorBeginOverlap 4、获取当前player&#xff1a;Get Player Pawn 5、判断是否相等&#xff1…

深入解析CSS中的!important规则:优先级与最佳实践

先上实践&#xff0c;再讨论设计 在实际工程中&#xff0c;!important 的使用场景通常出现在需要确保某个样式规则具有最高优先级&#xff0c;以覆盖其他可能冲突的样式规则时。以下是一个具体的例子&#xff1a; 场景描述 假设你正在开发一个网站&#xff0c;该网站使用了多…

JavaScript的数组与函数

数组 <script type"text/javascript">/** 知识点&#xff1a;数组* 理解&#xff1a;一维数组的容器* 概念&#xff1a;* 1.数组中的数据叫做元素* 2.元素都有编号叫做下标/索引* 3.下标从0开始* 注意&#xff1a;* 1.数组作为数据的容器…

【JavaScript脚本宇宙】状态管理利器:JavaScript 库全面解析

提升项目效率与可维护性&#xff1a;JavaScript 状态管理库大揭秘 前言 在现代前端开发中&#xff0c;状态管理是一个至关重要的话题。随着复杂性的增加&#xff0c;有效地管理应用程序的状态变得越来越具有挑战性。本文将介绍一些流行的 JavaScript 库&#xff0c;这些库提供…

WEB安全基础:网络安全常用术语

一、攻击类别 漏洞&#xff1a;硬件、软件、协议&#xff0c;代码层次的缺陷。 后⻔&#xff1a;方便后续进行系统留下的隐蔽后⻔程序。 病毒&#xff1a;一种可以自我复制并传播&#xff0c;感染计算机和网络系统的恶意软件(Malware)&#xff0c;它能损害数据、系统功能或拦…

C++语言学习精简笔记(包含C++20特性)

目录 1 C新语法C与CC编译运行String编程范式C基础类型**自动类型推导**统一对象初始化&#xff1a;Uniform Initialization 控制结构if语句for语句switch语句namespace 2 函数函数声明形式参数函数参数传递的选择函数返回值的选择 函数重载 Lambda表达式函数的定义和申明生存期…

磁力猫磁力搜索大全教程,如何使用磁力链接

磁力链接是一种特殊的下载链接&#xff0c;磁力链接可以理解为一个文件识别码&#xff0c;而并非具体的资源地址&#xff0c;下载软件需要拿着这个识别码去整个互联网(DHT网络)去寻找持有该资源的用户(节点)&#xff0c;如果找到则可以进行传输下载。一般年代越久远的磁力链接下…

【一】m2芯片的mac中安装ubuntu24虚拟机集群

文章目录 1. 虚拟机配置2. 复制虚拟机2.1 修改主机名2.2 修改网络 1. 虚拟机配置 在官方网站下载好ubuntu24-arm版镜像开始安装&#xff0c;安装使用VMWare Fusion的社区免费授权版,使用一台m2芯片的mac电脑作为物理机平台。 为什么选择ubuntu24&#xff1f;因为centOS7目前已…

Proteus + Keil单片机仿真教程(五)多位LED数码管的静态显示

Proteus + Keil单片机仿真教程(五)多位LED数码管 上一章节讲解了单个数码管的静态和动态显示,这一章节将对多个数码管的静态显示进行学习,本章节主要难点: 1.锁存器的理解和使用; 2.多个数码管的接线封装方式; 3.Proteus 快速接头的使用。 第一个多位数码管示例 元件…

『C + ⒈』‘\‘

&#x1f942;在反斜杠(\)有⒉种最常用的功能如下所示&#x1f44b; #define _CRT_SECURE_NO_WARNINGS 1 #include<stdio.h> int main(void) {int a 10;int b 20;int c 30;if (a 10 &&\b 20 &&\c 30){printf("Your print\n");}else{prin…

二分查找3

1. 有序数组中的单一元素&#xff08;540&#xff09; 题目描述&#xff1a; 算法原理&#xff1a; 二分查找解题关键就在于去找到数组的二段性&#xff0c;这里数组的二段性是从单个数字a开始出现然后分隔出来的&#xff0c;如果mid落入左半部分那么当mid为偶数时nums[mid1]…

ByteMD富文本编辑器的vue3配置

Git地址&#xff1a;GitHub - bytedance/bytemd: ByteMD v1 repository 控制面板输入 npm install bytemd/vue-next 下载成功后在src/main.ts中引用 import "bytemd/dist/index.css";引入后保存&#xff0c;下面是一些插件&#xff0c;比如说我用到gmf和hightLight&…

java后端向jsp传日期,jsp调用数据错误问题

问题 今天遇到个bug&#xff0c;后端使用request.setAttribute("key", value);将startDate、endDate两个日期字符串传递到jsp中&#xff0c;使jsp可以获取到日期进行查询操作。但接口拼接的参数startDate为2017&#xff0c;endDate为1986&#xff0c;让人百思不得其…