基于Qt状态机实现红绿灯、交通信号灯
场景需求:使用Qt状态机开发一个交通信号灯风格,要求三个状态(红、绿、黄)按预设时长自动循环切换,并实时显示剩余倒计时。
一、实现效果
- 视觉反馈
- 在Widget区域中循环切换红绿灯状态,显示红/绿/黄三种颜色
- Label同步显示当前状态标识文本和倒计时
- 逻辑控制
- 状态停留时长:红(5s)、绿(10s)、黄(3s)
- 精确到0.1秒的倒计时显示
- 自动无限循环状态切换
二、核心代码解析
1. 核心代码
QWidget *widget = ui->widget;
QLabel *label = ui->label;
QLabel *label2 = ui->label_2;
// 构建状态机和状态
QStateMachine *machine = new QStateMachine(this);
QState *s1 = new QState();
QState *s2 = new QState();
QState *s3 = new QState();
// 状态停留计时器
QTimer *timer = new QTimer(this);
// 状态改变时更新显示
s1->assignProperty(timer, "interval", 5000);
s2->assignProperty(timer, "interval", 10000);
s3->assignProperty(timer, "interval", 3000);
s1->assignProperty(label, "text", "s1 red");
s2->assignProperty(label, "text", "s2 green");
s3->assignProperty(label, "text", "s3 yellow");
s1->assignProperty(widget, "styleSheet", "background-color: red;");
s2->assignProperty(widget, "styleSheet", "background-color: green;");
s3->assignProperty(widget, "styleSheet", "background-color: yellow;");
// 状态循环,计时周期到达进入下一个状态事件
s1->addTransition(timer, &QTimer::timeout, s2);
s2->addTransition(timer, &QTimer::timeout, s3);
s3->addTransition(timer, &QTimer::timeout, s1);
// 添加到状态机中
machine->addState(s1);
machine->addState(s2);
machine->addState(s3);
machine->setInitialState(s1);
// 绑定状态机的开始和结束
connect(machine,&QStateMachine::started,timer,&QTimer::start);
connect(machine,&QStateMachine::stopped,timer,&QTimer::stop);
// 启动状态机
machine->start();
// 更新最新时间
QTimer *timer2 = new QTimer(this);
// 刷新间隔100ms
timer2->setInterval(100);
timer2->start();
connect(timer2,&QTimer::timeout, this,[=](){
// (timer->remainingTime()/100+9)/10)
// 这么写是为了让倒计时为0时也有一个周期的显示显示,即100ms
label2->setText(QString::number((timer->remainingTime()/100+9)/10));
});
技术仅供参考,欢迎沟通交流
附录:相关Qt类文档