Qt 状态机编程,双层状态机,实现暂停恢复

路流程
流程设计状态图

#ifndef WORKMACHINE_H
#define WORKMACHINE_H#include <QObject>
#include <QStateMachine>
#include <QHistoryState>
#include <QFinalState>#include "WorkThread.h"class WorkMachine : public QObject
{Q_OBJECT
public:explicit WorkMachine(QObject *parent = nullptr);~WorkMachine();void startMachine();void runMachineWorkFlow();void pauseMachine();void resumeMachine();signals:void sigMachineLog(QString log);void sigNextState();void sigPauseMachine();void sigResumeMachine();void sigMachineState(int state);private:void initMachine();void initStateTrans();void initWork();private:// 待机-》 (开门-》关门-》清洗-》甩干-》)  结束QStateMachine   m_machine;QState          *m_idleState;QState          *m_stateOpen;QState          *m_stateClose;QState          *m_groupStateWork;QState          *m_stateWash;QState          *m_stateDry;QState          *m_statePause;QHistoryState   *m_stateHistoryWork;bool            m_isPause;WorkThread      *m_workThread;
};#endif // WORKMACHINE_H
#include "WorkMachine.h"
#include <QDebug>WorkMachine::WorkMachine(QObject *parent): QObject{parent}
{initMachine();initStateTrans();initWork();m_isPause = false;
}WorkMachine::~WorkMachine()
{m_groupStateWork->deleteLater();
}void WorkMachine::startMachine()
{if (m_machine.isRunning()) {qDebug() << " ********* stop **********";m_machine.stop();emit sigMachineState(0);}else {qDebug() << "******** machine start work ********";m_machine.start();emit sigMachineState(1);//emit sigMachineLog("******** machine start work ********")}
}void WorkMachine::runMachineWorkFlow()
{emit sigNextState();
}void WorkMachine::pauseMachine()
{emit sigPauseMachine();m_isPause = true;
}void WorkMachine::resumeMachine()
{emit sigResumeMachine();m_isPause = false;
}void WorkMachine::initMachine()
{m_workThread = new WorkThread();m_idleState = new QState(&m_machine);m_idleState->setObjectName("initialState");m_statePause = new QState(&m_machine);m_statePause->setObjectName("pauseState");m_groupStateWork = new QState(&m_machine);m_groupStateWork->setObjectName("stateWork");m_stateOpen = new QState(m_groupStateWork);m_stateOpen->setObjectName("openState");QState *open1 = new QState(m_stateOpen);open1->setObjectName("open1State");QState *open2 = new QState(m_stateOpen);QFinalState *openFinal  = new QFinalState(m_stateOpen);open2->setObjectName("open2State");m_stateOpen->setInitialState(open1);open1->addTransition(this, &WorkMachine::sigNextState, open2);open2->addTransition(this, &WorkMachine::sigNextState, openFinal);connect(open1, &QState::entered, this, [this](){m_workThread->startTask("step 1 open1", 500);});connect(open2, &QState::entered, this, [this](){m_workThread->startTask("step 1 open2", 500);});m_stateClose = new QState(m_groupStateWork);m_stateClose->setObjectName("closeState");m_stateWash = new QState(m_groupStateWork);m_stateWash->setObjectName("stateWash");m_stateDry = new QState(m_groupStateWork);m_stateDry->setObjectName("stateDry");m_stateHistoryWork = new QHistoryState(m_groupStateWork);m_stateHistoryWork->setObjectName("historyState");m_stateHistoryWork->setDefaultState(m_stateWash);m_stateHistoryWork->setHistoryType(QHistoryState::DeepHistory);m_groupStateWork->setChildMode(QState::ExclusiveStates);m_groupStateWork->setInitialState(m_stateHistoryWork);m_machine.setInitialState(m_idleState);
}void WorkMachine::initStateTrans()
{m_groupStateWork->addTransition(this, &WorkMachine::sigPauseMachine, m_statePause);m_statePause->addTransition(this, &WorkMachine::sigResumeMachine, m_stateHistoryWork);connect(m_workThread, &WorkThread::finished, this, [this](){if (m_isPause) {}else {emit sigNextState();}});m_idleState->addTransition(this, &WorkMachine::sigNextState, m_stateOpen);//m_stateOpen->addTransition(this, &WorkMachine::sigNextState, m_stateClose);m_stateOpen->addTransition(m_stateOpen, &QState::finished, m_stateClose);m_stateClose->addTransition(this, &WorkMachine::sigNextState, m_stateWash);m_stateWash->addTransition(this, &WorkMachine::sigNextState, m_stateDry);m_stateDry->addTransition(this, &WorkMachine::sigNextState, m_idleState);
}void WorkMachine::initWork()
{connect(m_idleState, &QState::entered, this, [this](){qDebug() << "init state";});connect(m_stateHistoryWork, &QState::entered, this, [this](){qDebug() << "m_stateHistoryWork state enter";});connect(m_stateOpen, &QState::entered, this, [this](){m_workThread->startTask("step 1 Open");});connect(m_stateClose, &QState::entered, this, [this](){m_workThread->startTask("step 2 Close");});connect(m_groupStateWork, &QState::entered, this, [this](){qDebug() << "Work state enter";});connect(m_stateWash, &QState::entered, this, [this](){m_workThread->startTask("step 3 Wash", 2000);});connect(m_stateDry, &QState::entered, this, [this](){m_workThread->startTask("step 4 Dry", 2000);});connect(m_statePause, &QState::entered, this, [this](){qDebug() << "pause";});
}
#ifndef WORKTHREAD_H
#define WORKTHREAD_H#include <QObject>
#include <QThread>class WorkThread: public QThread
{
public:WorkThread();void startTask(QString log, int timems=500);void run() override;private:QString   m_log;int       m_time;
};#endif // WORKTHREAD_H
#include "WorkThread.h"
#include <QDebug>WorkThread::WorkThread() {}void WorkThread::startTask(QString log, int timems)
{m_log = log;m_time = timems;this->start();
}void WorkThread::run()
{QThread::msleep(100);qDebug() << m_log  + " start running ...";QThread::msleep(m_time);qDebug() << m_log  + " end";
}

UI 控制类

#ifndef WIDGET_H
#define WIDGET_H#include <QWidget>
#include "WorkMachine.h"QT_BEGIN_NAMESPACE
namespace Ui {
class Widget;
}
QT_END_NAMESPACEclass Widget : public QWidget
{Q_OBJECTpublic:Widget(QWidget *parent = nullptr);~Widget();private slots:void on_btnRun_clicked();private:Ui::Widget *ui;WorkMachine  m_machine;
};
#endif // WIDGET_H
#include "widget.h"
#include "ui_widget.h"Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget)
{ui->setupUi(this);connect(ui->btnStart, &QPushButton::clicked, this, [this](){m_machine.startMachine();});connect(ui->btnPause, &QPushButton::clicked, this, [this](){m_machine.pauseMachine();});connect(ui->btnResume, &QPushButton::clicked, this, [this](){m_machine.resumeMachine();});connect(&m_machine, &WorkMachine::sigMachineState, this, [this](bool isRun){ui->btnPause->setEnabled(isRun);});
}Widget::~Widget()
{delete ui;
}void Widget::on_btnRun_clicked()
{m_machine.runMachineWorkFlow();
}

设计思路:
1 .每个状态对应一个流程
2. 每个状态进入后开始执行流程动作
3. 状态进入流程开始执行,执行结束线程结束
4. 线程结束信号控制转移到下一个状态,也就是下一个流程继续往下走
5. 暂停时候主动触发 pause 信号状态机从 work 状态跳出到 pause 状态
6. 恢复时候从 pause 状态回到 history 状态,根据需要设置历史状态深浅,是否记录子状态,还是只记录第一层状态
7. 每个子状态流程末尾使用 final 状态标记,使用他的finished 信号进行状态转移
8. 每个子状态设置初始状态,也就是子状态第一个状态

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

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

相关文章

记录可编辑表格(未完整)

每一行都独立 <el-table-column label"操作" width"220" fixed"right"><template #default"{ row, $index }"><el-buttonv-if"!row.tableEditFlag"type"primary"size"small"click"…

螺栓与散装物体检测系统源码分享

螺栓与散装物体检测检测系统源码分享 [一条龙教学YOLOV8标注好的数据集一键训练_70全套改进创新点发刊_Web前端展示] 1.研究背景与意义 项目参考AAAI Association for the Advancement of Artificial Intelligence 项目来源AACV Association for the Advancement of Comput…

[云服务器12] 搭建eaglercraft网页MC

众所周知&#xff0c;MC是一个炒鸡好玩的游戏&#xff01; 但是&#xff0c;Mojang开发出来是经过Java JAR打包过的的.jar文件&#xff0c;这就不得不依赖HMCL PCL BakaXL等启动器来启动了…… 所以今天&#xff0c;我们将使用开源的eaglercraft来搭建一个在线版MC&#xff0…

誉龙视音频 Third/TimeSyn 远程命令执行复现

0x01 漏洞描述&#xff1a; 誉龙公司定位为系统级的移动视音频记录解决方案提供商&#xff0c;凭借其深厚的行业经验&#xff0c;坚持自主研发&#xff0c;匠心打造记录仪领域行业生态&#xff0c;提供开放式的记录仪APK、GB28181 SDK、国网B协议、管理平台软件OEM。誉龙视音频…

C/S架构与B/S架构的适用场景分析

C/S架构&#xff08;客户端/服务器架构&#xff09;与B/S架构&#xff08;浏览器/服务器架构&#xff09;在适用场景上各有特点&#xff0c;主要取决于应用的具体需求、用户群体、系统维护成本、跨平台需求等因素。 一、C/S架构的适用场景 1、高性能与交互性要求高的应用&…

9月26日云技术研讨会 | SOA整车EE架构开发流程及工具实施方案

面向服务的架构&#xff08;Service Oriented Architecture, SOA&#xff09;实施需要复杂的基础技术作为支撑&#xff0c;伴随着整车硬件资源的集中化、车载以太网等高速通信技术在车内的部署&#xff0c;将在未来一段时间内成为行业技术研究和市场布局的热点。 近年来&#x…

使用Webpack创建vue脚手架并搭建路由---详解

1.使用 vue 库 vue 是一个非常好用的 javascript 库&#xff0c;现在已经发行了 vue 3&#xff0c;我们可以直接导入使用库文件&#xff0c;也可以使用单文件&#xff08;SFC&#xff09;的形式&#xff0c;直接使用库文件会简单一点&#xff0c;我们先来试一下吧。 1.1安装 v…

JdbcTemplate常用方法一览AG网页参数绑定与数据寻址实操

JdbcTemplate是Spring框架中的一个重要组件&#xff0c;主要用于简化JDBC数据库操作。它提供了许多常用的方法&#xff0c;如查询、插入、更新、删除等。本文将介绍JdbcTemplate的常用方法及其使用方式&#xff0c;以及参数绑定和删除数据的方法。 一、JdbcTemplate常用方法 查…

24/9/19 算法笔记 kaggle BankChurn数据分类

题目是要预测银行里什么样的客户会流失&#xff0c;流失的概率是多少 我这边先展示一下我写的二分类的算法 import numpy as np import pandas as pd import matplotlib.pyplot as plt from sklearn.model_selection import train_test_split from sklearn.linear_model impo…

金砖软件测试赛项之Jmeter如何录制脚本!

一、简介 Apache JMeter 是一款开源的性能测试工具&#xff0c;用于测试各种服务的负载能力&#xff0c;包括Web应用、数据库、FTP服务器等。它可以模拟多种用户行为&#xff0c;生成负载以评估系统的性能和稳定性。 JMeter 的主要特点&#xff1a; 图形用户界面&#xff1a;…

Stable Diffusion绘画 | ControlNet应用-IP-Adapter:一致性角色就这么简单

IP-Adapter 更新了全新的模型—FaceID plus V2 版本&#xff0c;同时还支持 SDXL 模型。 FaceID plus V2 版本的优点&#xff1a; 解决任务一致性 一张图生成相似角色 下载地址&#xff1a;https://huggingface.co/h94/IP-Adapter-FaceID/tree/main 其中&#xff0c;两个 Lora文…

AIGC时代!AI的“iPhone时刻”与投资机遇

AIGC时代&#xff01;AI的“iPhone时刻”与投资机遇 前言AI的“iPhone时刻”与投资机遇 前言 AIGC&#xff0c;也就是人工智能生成内容&#xff0c;它就像是一股汹涌的浪潮&#xff0c;席卷了整个科技世界。它的出现&#xff0c;让我们看到了人工智能的无限潜力&#xff0c;也…

基于协同过滤算法+PHP的新闻推荐系统

作者&#xff1a;计算机学姐 开发技术&#xff1a;SpringBoot、SSM、Vue、MySQL、JSP、ElementUI、Python、小程序等&#xff0c;“文末源码”。 专栏推荐&#xff1a;前后端分离项目源码、SpringBoot项目源码、SSM项目源码 系统展示 【2025最新】基于协同过滤算法PHPMySQL的新…

【STM32 HAL库】OLED显示模块

【STM32 HAL库】OLED显示模块 前言理论OLED基本参数OLED基本驱动原理OLED坐标轴 应用CubeMx配置底层函数代码高层封装函数printf显示函数 前言 本文为笔者学习 OLED 的总结&#xff0c;基于keysking的视频内容&#xff0c;如有错误&#xff0c;欢迎指正 理论 OLED基本参数 …

react + antDesign封装图片预览组件(支持多张图片)

需求场景&#xff1a;最近在开发后台系统时经常遇到图片预览问题&#xff0c;如果一个一个的引用antDesign的图片预览组件就有点繁琐了&#xff0c;于是在antDesign图片预览组件的基础上二次封装了一下&#xff0c;避免重复无用代码的出现 效果 公共预览组件代码 import React…

【machine learning-十-grading descent梯度下降实现】

grading descent 梯度下降参数更新方法 --导数和学习率 从导数项直观理解梯度下降 grading descent 算法就是更新参数&#xff0c;今天来学习下如何更新w和b 梯度下降 还是以线性回归的均方差损失函数如下为例&#xff1a; 损失函数的可视化图如下 &#xff1a; 横轴和纵轴分…

影刀RPA实战:网页爬虫之苦瓜书籍数据

书籍常常被视为心灵的慰藉&#xff0c;因为它们能够在不同的层面上为人们提供支持和安慰。 1. 书籍对我们的重要性 书籍是人类知识的载体&#xff0c;也是智慧的结晶。它们不仅是学习的工具&#xff0c;更是人类心灵的慰藉。在忙碌的生活中&#xff0c;书籍能够提供知识、启发…

魅思CMS getOrderStatus SQL注入漏洞复现

0x01 漏洞描述&#xff1a; 魅思是一款集成了视频管理、用户管理、手机端应用封装等功能的综合性视频管理系统。该系统不仅以其强大的视频管理功能、灵活的用户管理机制、便捷的手机端应用封装功能以及高安全性和现代化的界面设计&#xff0c;成为了市场上备受关注的视频管理系…

技术美术百人计划 | 《4.5 DOF景深算法》笔记

1. 景深定义 景深&#xff08;Depth of Field&#xff0c;DOF&#xff09;&#xff0c;是指在摄影机镜头或其他成像器前沿能够取得清晰图像的成像所测定的被摄物体前后距离范围。镜头光圈、镜头焦距、及焦平面到拍摄物的距离是影响景深的重要因素。在聚焦完成后&#xff0c;焦点…

监控IDS和IPS增强网络安全性

入侵检测系统&#xff08;IDS&#xff09;和入侵防御系统&#xff08;IPS&#xff09;是当今使用的最复杂的网络安全设备之一&#xff0c;它们检查网络数据包并阻止可疑数据包&#xff0c;并提醒管理员有关攻击企图的信息。 在当今威胁不断变化的网络环境中&#xff0c;防火墙…