下面是一个使用 QStateMachine
的简单示例,模拟任务的状态机控制,包含以下状态:
- Idle(空闲)
- Running(运行中)
- Paused(暂停)
- Stopped(停止)
- Finished(完成)
这个例子使用 Qt Widgets 和 Qt 状态机模块(Qt5 或 Qt6)。它创建了一个简单的 GUI,包含几个按钮用于控制状态转换,以及一个状态机来管理状态和过渡。
完整示例代码
1. mainwindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <QStateMachine>
#include <QState>
#include <QFinalState>
QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACE
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
MainWindow(QWidget *parent = nullptr);
~MainWindow();
private:
Ui::MainWindow *ui;
QStateMachine *stateMachine;
QState *idleState;
QState *runningState;
QState *pausedState;
QState *stoppedState;
QFinalState *finishedState;
};
#endif // MAINWINDOW_H
2. mainwindow.cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QPushButton>
#include <QLabel>
#include <QVBoxLayout>
#include <QDebug>
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
ui->setupUi(this);
auto *centralWidget = new QWidget(this);
setCentralWidget(centralWidget);
auto *layout = new QVBoxLayout(centralWidget);
QLabel *statusLabel = new QLabel("Status: Idle", this);
QPushButton *startButton = new QPushButton("Start", this);
QPushButton *pauseButton = new QPushButton("Pause", this);
QPushButton *resumeButton = new QPushButton("Resume", this);
QPushButton *stopButton = new QPushButton("Stop", this);
layout->addWidget(statusLabel);
layout->addWidget(startButton);
layout->addWidget(pauseButton);
layout->addWidget(resumeButton);
layout->addWidget(stopButton);
stateMachine = new QStateMachine(this);
idleState = new QState();
runningState = new QState();
pausedState = new QState();
stoppedState = new QState();
finishedState = new QFinalState();
// Define state transitions
idleState->addTransition(startButton, &QPushButton::clicked, runningState);
runningState->addTransition(pauseButton, &QPushButton::clicked, pausedState);
pausedState->addTransition(resumeButton, &QPushButton::clicked, runningState);
runningState->addTransition(stopButton, &QPushButton::clicked, stoppedState);
pausedState->addTransition(stopButton, &QPushButton::clicked, stoppedState);
stoppedState->addTransition(stopButton, &QPushButton::clicked, finishedState);
// Define state actions
connect(idleState, &QState::entered, [statusLabel]() {
statusLabel->setText("Status: Idle");
qDebug() << "Entering Idle State";
});
connect(runningState, &QState::entered, [statusLabel]() {
statusLabel->setText("Status: Running");
qDebug() << "Entering Running State";
});
connect(pausedState, &QState::entered, [statusLabel]() {
statusLabel->setText("Status: Paused");
qDebug() << "Entering Paused State";
});
connect(stoppedState, &QState::entered, [statusLabel]() {
statusLabel->setText("Status: Stopped");
qDebug() << "Entering Stopped State";
});
connect(finishedState, &QFinalState::entered, [statusLabel]() {
statusLabel->setText("Status: Finished");
qDebug() << "Entering Finished State";
});
// Setup state machine
stateMachine->addState(idleState);
stateMachine->addState(runningState);
stateMachine->addState(pausedState);
stateMachine->addState(stoppedState);
stateMachine->addState(finishedState);
stateMachine->setInitialState(idleState);
stateMachine->start();
}
MainWindow::~MainWindow() {
delete ui;
}
3. main.cpp
#include <QApplication>
#include "mainwindow.h"
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MainWindow w;
w.show();
return a.exec();
}
解释
-
状态定义:
idleState
(空闲):初始状态。runningState
(运行中):当任务开始时。pausedState
(暂停):任务暂停时。stoppedState
(停止):任务停止时。finishedState
(完成):任务完成时。
-
状态过渡:
- 从
idleState
通过点击 "Start" 进入runningState
。 - 从
runningState
通过点击 "Pause" 进入pausedState
。 - 从
pausedState
通过点击 "Resume" 进入runningState
。 - 从
runningState
或pausedState
通过点击 "Stop" 进入stoppedState
。 - 从
stoppedState
通过点击 "Stop" 进入finishedState
。
- 从
-
状态动作:
- 在每个状态的
entered
信号中,更新标签文本并打印调试信息。
- 在每个状态的
构建和运行
确保你的 .pro
文件或 CMakeLists.txt
包含对 Qt Widgets 和 State Machine 模块的支持,并构建项目。运行应用程序,你将看到一个简单的 GUI 界面,能够根据按钮点击模拟任务的状态转换。