当前位置: 首页 > news >正文

Qt之QStateMachine等待

在项目中经常需要等待,我们模拟0-30的数,假如我们其中5, 25的数需要进行等待,等待用户处理完自己事情后,按下按钮继续,找Qt的项目中有一个

QStateMachine

qstatemmachine类提供了一个分层有限状态机。
QStateMachine基于Statecharts的概念和符号。qstatemmachine是状态机框架的一部分。
状态机管理一组状态(从QAbstractState继承的类)和这些状态之间的转换(QAbstractTransition的后代);这些状态和转换定义了一个状态图。一旦构建了状态图,状态机就可以执行它。qstatemmachine的执行算法基于状态图XML (SCXML)算法。该框架的概述给出了几个状态图和构建它们的代码。
使用addState()函数向状态机添加顶级状态。使用removeState()函数删除状态。不鼓励在机器运行时删除状态。
在机器启动之前,必须设置初始状态。初始状态是机器启动时进入的状态。然后可以启动状态机。当进入初始状态时,就会发出started()信号。
机器是事件驱动的,并保持自己的事件循环。事件通过postEvent()发送到机器。请注意,这意味着它是异步执行的,并且如果没有正在运行的事件循环,它将无法进行。你通常不需要将事件直接发布到机器上,因为Qt的转换,例如,QEventTransition和它的子类,会处理这个。但是对于由事件触发的自定义转换,postEvent()很有用。
状态机处理事件并进行转换,直到进入顶级最终状态;然后状态机发出finished()信号。您还可以显式地stop()状态机。在这种情况下,会发出stopped()信号。
下面的代码片段显示了一个状态机,当按钮被点击时,状态机将完成:

QPushButton button;QStateMachine machine;QState *s1 = new QState();s1->assignProperty(&button, "text", "Click me");QFinalState *s2 = new QFinalState();s1->addTransition(&button, SIGNAL(clicked()), s2);machine.addState(s1);machine.addState(s2);machine.setInitialState(s1);machine.start();

那么我们实现自己

Processor类
#ifndef PROCESSOR_H
#define PROCESSOR_H#include <QObject>
#include <QStateMachine>
#include <QState>
#include <QFinalState>class Processor : public QObject
{Q_OBJECT
public:explicit Processor(QObject *parent = nullptr);void startProcessing();void resumeProcessing();signals:void progressUpdated(int value);void runSig();void paused();void finished();private:void processNextItem();bool isRunning() const;private:QStateMachine *m_machine;QState *m_runningState;QState *m_pausedState;QFinalState *m_finishedState;int m_currentIndex;
};#endif // PROCESSOR_H
#include "processor.h"
#include <QDebug>
#include <QTimer>
#include <QThread>Processor::Processor(QObject *parent): QObject(parent),m_machine(new QStateMachine(this)),m_runningState(new QState(m_machine)),m_pausedState(new QState(m_machine)),m_finishedState(new QFinalState(m_machine)),m_currentIndex(0)
{// 配置运行状态connect(m_runningState, &QState::entered, [this]() {qDebug() << "Entered running state";processNextItem();});// 配置暂停状态connect(m_pausedState, &QState::entered, [this]() {qDebug() << "Entered paused state";});// 配置暂停状态
//    connect(m_finishedState, &QState::entered, [this]() {
//        qDebug() << "Entered finished state";
//    });// 配置状态转换m_runningState->addTransition(this, &Processor::paused, m_pausedState);m_pausedState->addTransition(this, &Processor::runSig, m_runningState);m_runningState->addTransition(this, &Processor::finished, m_finishedState);// 配置状态机m_machine->setInitialState(m_runningState);}bool Processor::isRunning() const
{return m_machine->isRunning();
}void Processor::startProcessing()
{if (!m_machine->isRunning()) {qDebug() << "Starting processing...";m_machine->start();}
}void Processor::resumeProcessing()
{++m_currentIndex;emit runSig();}void Processor::processNextItem()
{if (m_currentIndex >= 30) {emit finished();return;}emit progressUpdated(m_currentIndex);if (m_currentIndex == 5 || m_currentIndex == 25) {qDebug() << "--- Reached pause point ---";emit paused();}else { // 只有非暂停点时继续自动处理m_currentIndex++;QThread::msleep(200);       //模拟耗时操作processNextItem();}
}

单例模式

#ifndef TASKPROCESSOR_H
#define TASKPROCESSOR_H#include <QObject>
#include <QStateMachine>
#include <QState>
#include <QFinalState>
#include <QQueue>
#include <QMutex>
#include <functional>class TaskProcessor : public QObject
{Q_OBJECT
public:// 单例接口,保证全局唯一static TaskProcessor& getInstance() {static TaskProcessor processor;return processor;}// 添加任务到队列void addTask(const std::function<void()>& task);// 开始处理任务队列void startProcessing();// 暂停任务处理(例如等待外部事件)void pauseProcessing();// 恢复任务处理void resumeProcessing();signals:// 任务状态信号,可根据需求扩展void pausedSig();void resumeSig();void taskStarted();void taskFinished();void allTasksFinished();private:// 构造函数私有,确保单例explicit TaskProcessor(QObject *parent = nullptr);Q_DISABLE_COPY(TaskProcessor)// 内部处理任务队列的方法void processNextTask();// 任务队列及同步保护QQueue<std::function<void()>> m_taskQueue;QMutex m_mutex;// 状态机及状态QStateMachine *m_machine;QState *m_runningState;QState *m_pausedState;QFinalState *m_finishedState;
};#endif // TASKPROCESSOR_H
#include "processor.h"
#include <QDebug>
#include <QThread>TaskProcessor::TaskProcessor(QObject *parent): QObject(parent),m_machine(new QStateMachine(this)),m_runningState(new QState(m_machine)),m_pausedState(new QState(m_machine)),m_finishedState(new QFinalState(m_machine))
{// 配置运行状态:进入运行状态时,尝试处理下一个任务connect(m_runningState, &QState::entered, this, [this]() {qDebug() << "Entered running state";processNextTask();});// 配置暂停状态:仅做记录,具体暂停逻辑可通过状态机外部控制connect(m_pausedState, &QState::entered, this, [this]() {qDebug() << "Entered paused state";});// 状态切换配置:暂停和恢复m_runningState->addTransition(this, SIGNAL(pausedSig()), m_pausedState);m_pausedState->addTransition(this, SIGNAL(resumeSig()), m_runningState);// 当任务全部处理完毕时,切换到结束状态m_runningState->addTransition(this, SIGNAL(allTasksFinished()), m_finishedState);// 状态机初始状态设为运行状态m_machine->setInitialState(m_runningState);
}void TaskProcessor::addTask(const std::function<void()>& task)
{QMutexLocker locker(&m_mutex);m_taskQueue.enqueue(task);
}void TaskProcessor::startProcessing()
{if (!m_machine->isRunning()) {qDebug() << "Starting Task Processing...";m_machine->start();}
}void TaskProcessor::pauseProcessing()
{// 可以发出信号通知状态机进入暂停状态qDebug() << "Requesting pause...";emit pausedSig();  // 此处 SIGNAL 与状态机转换绑定
}void TaskProcessor::resumeProcessing()
{// 发出信号恢复处理qDebug() << "Requesting resume...";emit resumeSig();processNextTask();
}void TaskProcessor::processNextTask()
{QMutexLocker locker(&m_mutex);if (m_taskQueue.isEmpty()) {qDebug() << "All tasks finished.";emit allTasksFinished();return;}// 取出队列中的下一个任务std::function<void()> task = m_taskQueue.dequeue();// 在运行状态下开始任务,发出任务开始信号emit taskStarted();qDebug() << "Processing a task...";// 这里可以在一个独立线程中运行任务,避免阻塞状态机// 例如:QThread::sleep() 或者使用 QtConcurrenttask();// 任务执行完成,发出任务结束信号emit taskFinished();}

相关文章:

Qt之QStateMachine等待

在项目中经常需要等待&#xff0c;我们模拟0-30的数&#xff0c;假如我们其中5&#xff0c; 25的数需要进行等待&#xff0c;等待用户处理完自己事情后&#xff0c;按下按钮继续&#xff0c;找Qt的项目中有一个 QStateMachineqstatemmachine类提供了一个分层有限状态机。 QSta…...

Wireshark 插件开发实战指南

Wireshark 插件开发实战指南 环境搭建流程图 #mermaid-svg-XpNibno7BIyfzNn5 {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-XpNibno7BIyfzNn5 .error-icon{fill:#552222;}#mermaid-svg-XpNibno7BIyfzNn5 .error-t…...

基于SpringBoot的“青少年心理健康教育网站”的设计与实现(源码+数据库+文档+PPT)

基于SpringBoot的“青少年心理健康教育网站”的设计与实现&#xff08;源码数据库文档PPT) 开发语言&#xff1a;Java 数据库&#xff1a;MySQL 技术&#xff1a;SpringBoot 工具&#xff1a;IDEA/Ecilpse、Navicat、Maven 系统展示 系统总体结构图 实体属性图 系统首页界…...

23-整数转罗马数字

代码 测试用例 测试结果 测试结果 12. 整数转罗马数字 中等 相关标签 相关企业 七个不同的符号代表罗马数字&#xff0c;其值如下&#xff1a; 符号值I1V5X10L50C100D500M1000 罗马数字是通过添加从最高到最低的小数位值的转换而形成的。将小数位值转换为罗马数字有以…...

SpringBoot+Redis+Mybatis-plus黑马点评

短信登录 基于Session实现登录 流程&#xff1a; 发送短信验证码-->短信验证码注册登录-->校验登录状态&#xff08;保存用户到ThreadLocal&#xff0c;方便后续使用&#xff09; 不能每次请求服务都要进行登录状态校验&#xff0c;解决办法&#xff1a;拦截器 在Sp…...

深入剖析 OpenCV:全面掌握基础操作、图像处理算法与特征匹配

深入剖析 OpenCV&#xff1a;全面掌握基础操作、图像处理算法与特征匹配 一、引言二、OpenCV 的安装&#xff08;一&#xff09;使用 pip 安装&#xff08;二&#xff09;使用 Anaconda 安装 三、OpenCV 基础操作&#xff08;一&#xff09;图像的读取、显示与保存&#xff08;…...

【C语言显示Linux系统参数】

在C语言中&#xff0c;可以通过调用Linux系统提供的API来获取和显示系统参数。以下是一些常见的系统参数及其获取方法&#xff1a; 1. 获取系统名称和版本 可以使用uname函数来获取系统名称、版本等信息。 #include <stdio.h> #include <sys/utsname.h>int main…...

突破Ajax跨域困境,解锁前端通信新姿势

一、引言 在当今的 Web 开发领域&#xff0c;前后端分离的架构模式已经成为主流&#xff0c;它极大地提升了开发效率和项目的可维护性。在这种开发模式下&#xff0c;前端通过 Ajax 技术与后端进行数据交互&#xff0c;然而&#xff0c;跨域问题却如影随形&#xff0c;成为了开…...

Kotlin协变与逆变区别

在Kotlin中&#xff0c;协变和逆变是泛型编程中的两个重要概念&#xff0c;它们允许我们在类型系统中更加灵活地处理类型关系。 1.协变&#xff1a;协变允许我们使用比原始类型更具体的类型。在kotlin中&#xff0c;通过在类型参数上加out关键字来表示协变,生产者&#xff0c;例…...

driver中为什么要使用非阻塞赋值

1. 模拟硬件时序行为 实际硬件行为&#xff1a;DUT的输入信号通常在时钟边沿被采样。Driver需要确保信号的更新与时钟同步&#xff0c;而非阻塞赋值的延迟更新特性&#xff08;在时间步结束时统一生效&#xff09;能够准确模拟寄存器的行为。 示例&#xff1a; always (posedg…...

模板字符串【ES6】

“路漫漫其修远兮&#xff0c;吾将上下而求索。”—— 屈原《离骚》 目录 什么是模板字符串&#xff1f;模板字符串特性及代码举例&#xff1a;详细举例用法&#xff1a; 什么是模板字符串&#xff1f; 模板字符串&#xff08;Template Literals&#xff09;是JavaScript中引入…...

通往 AI 之路:Python 机器学习入门-数据结构

Python 数据结构 Python 提供了多种数据结构来存储和操作数据&#xff0c;其中列表&#xff08;list&#xff09;、字典&#xff08;dict&#xff09;、元组&#xff08;tuple&#xff09;和集合&#xff08;set&#xff09;是最常用的几种。本章将详细介绍这些数据结构的基本…...

我们应该如何优化UI(基于UGUI)

这是一道面试题&#xff0c;下面&#xff0c;我们来详细分析这个问题。 目录 1. 减少 Draw Call 合理设置图集 避免材质和 Shader 的频繁切换 减少 UI 元素的重叠 2. 优化UI布局 3. 优化UI元素的渲染 4.优化UI动画 5. 优化 UI 事件处理 6. 运行时优化 1. 减少 Draw C…...

CSS3 圆角:实现与优化指南

CSS3 圆角&#xff1a;实现与优化指南 随着网页设计的发展&#xff0c;CSS3 圆角已经成为了现代网页设计中不可或缺的元素之一。本文将详细讲解 CSS3 圆角的基本用法、实现方式以及优化技巧&#xff0c;帮助您在网页设计中更好地运用这一功能。 一、CSS3 圆角基本用法 1.1 基…...

【网络安全 | 扫描子域+发现真实IP】CloakQuest3r安装使用详细教程

原创文章,禁止转载。 本文仅作学习交流使用,不得用于非法渗透,笔者不承担任何责任。 文章目录 简介功能介绍执行流程限制安装步骤可选功能:SecurityTrails API使用示例简介 CloakQuest3r 是一款强大的 Python 工具,专为揭示受 Cloudflare 及类似服务保护的网站真实 IP 地…...

Mellanox OFED驱动如何给全局编译添加gcc的编译选项?(subdir-ccflags-y += -Wall)

背景 有些时候编译驱动需要给全局加一个编译选项&#xff0c;假设configure已经完成。可以直接在Makefile中修改 添加方式 修改OFED驱动目录下的&#xff1a; ./Makefile subdir-ccflags-y -Wall修改效果&#xff1a; 然后执行make&#xff0c;就能让添加的编译选项生效…...

【愚公系列】《Python网络爬虫从入门到精通》037-文件的存取

标题详情作者简介愚公搬代码头衔华为云特约编辑,华为云云享专家,华为开发者专家,华为产品云测专家,CSDN博客专家,CSDN商业化专家,阿里云专家博主,阿里云签约作者,腾讯云优秀博主,腾讯云内容共创官,掘金优秀博主,亚马逊技领云博主,51CTO博客专家等。近期荣誉2022年度…...

【一起学Rust | Tauri2.0框架】单实例应用程序的深入解析:零漏洞实现与优化实战

文章目录 前言一、 单实例应用的意义二、 实现单实例应用的方法1 Windows下的实现1.1 创建命名Mutex1.2 在Tauri应用中集成Mutex检查 2 macOS下的实现2.1 获取Bundle Identifier2.2 检查是否已经有实例在运行 3 Linux下的实现3.1 获取进程列表3.2 检查是否已经有实例在运行 4 在…...

PhyloSuite v1.2.3安装与使用-生信工具049

PhyloSuite 一个好用的win集成建树平台&#xff0c;官方相关文档视频等做的可好了PhyloSuite (jushengwu.com) 官网 https://github.com/dongzhang0725/PhyloSuite/releases #官网 http://phylosuite.jushengwu.com/dongzhang0725.github.io/installation/ #官方说明文档…...

使用Apache Lucene构建高效的全文搜索服务

使用Apache Lucene构建高效的全文搜索服务 在现代应用程序中&#xff0c;全文搜索功能是不可或缺的一部分。无论是电子商务网站、内容管理系统&#xff0c;还是数据分析平台&#xff0c;快速、准确地搜索大量数据是提升用户体验的关键。Apache Lucene 是一个强大的全文搜索引擎…...

IDEA运行Tomcat出现乱码问题解决汇总

最近正值期末周&#xff0c;有很多同学在写期末Java web作业时&#xff0c;运行tomcat出现乱码问题&#xff0c;经过多次解决与研究&#xff0c;我做了如下整理&#xff1a; 原因&#xff1a; IDEA本身编码与tomcat的编码与Windows编码不同导致&#xff0c;Windows 系统控制台…...

国防科技大学计算机基础课程笔记02信息编码

1.机内码和国标码 国标码就是我们非常熟悉的这个GB2312,但是因为都是16进制&#xff0c;因此这个了16进制的数据既可以翻译成为这个机器码&#xff0c;也可以翻译成为这个国标码&#xff0c;所以这个时候很容易会出现这个歧义的情况&#xff1b; 因此&#xff0c;我们的这个国…...

微信小程序之bind和catch

这两个呢&#xff0c;都是绑定事件用的&#xff0c;具体使用有些小区别。 官方文档&#xff1a; 事件冒泡处理不同 bind&#xff1a;绑定的事件会向上冒泡&#xff0c;即触发当前组件的事件后&#xff0c;还会继续触发父组件的相同事件。例如&#xff0c;有一个子视图绑定了b…...

电脑插入多块移动硬盘后经常出现卡顿和蓝屏

当电脑在插入多块移动硬盘后频繁出现卡顿和蓝屏问题时&#xff0c;可能涉及硬件资源冲突、驱动兼容性、供电不足或系统设置等多方面原因。以下是逐步排查和解决方案&#xff1a; 1. 检查电源供电问题 问题原因&#xff1a;多块移动硬盘同时运行可能导致USB接口供电不足&#x…...

基于当前项目通过npm包形式暴露公共组件

1.package.sjon文件配置 其中xh-flowable就是暴露出去的npm包名 2.创建tpyes文件夹&#xff0c;并新增内容 3.创建package文件夹...

基于Docker Compose部署Java微服务项目

一. 创建根项目 根项目&#xff08;父项目&#xff09;主要用于依赖管理 一些需要注意的点&#xff1a; 打包方式需要为 pom<modules>里需要注册子模块不要引入maven的打包插件&#xff0c;否则打包时会出问题 <?xml version"1.0" encoding"UTF-8…...

【Java_EE】Spring MVC

目录 Spring Web MVC ​编辑注解 RestController RequestMapping RequestParam RequestParam RequestBody PathVariable RequestPart 参数传递 注意事项 ​编辑参数重命名 RequestParam ​编辑​编辑传递集合 RequestParam 传递JSON数据 ​编辑RequestBody ​…...

鱼香ros docker配置镜像报错:https://registry-1.docker.io/v2/

使用鱼香ros一件安装docker时的https://registry-1.docker.io/v2/问题 一键安装指令 wget http://fishros.com/install -O fishros && . fishros出现问题&#xff1a;docker pull 失败 网络不同&#xff0c;需要使用镜像源 按照如下步骤操作 sudo vi /etc/docker/dae…...

AI编程--插件对比分析:CodeRider、GitHub Copilot及其他

AI编程插件对比分析&#xff1a;CodeRider、GitHub Copilot及其他 随着人工智能技术的快速发展&#xff0c;AI编程插件已成为提升开发者生产力的重要工具。CodeRider和GitHub Copilot作为市场上的领先者&#xff0c;分别以其独特的特性和生态系统吸引了大量开发者。本文将从功…...

自然语言处理——Transformer

自然语言处理——Transformer 自注意力机制多头注意力机制Transformer 虽然循环神经网络可以对具有序列特性的数据非常有效&#xff0c;它能挖掘数据中的时序信息以及语义信息&#xff0c;但是它有一个很大的缺陷——很难并行化。 我们可以考虑用CNN来替代RNN&#xff0c;但是…...