在 Qt 中计时事件的最佳方式
Best way to timing events in Qt
我正在用 Qt/c++ 编写一个软件,通过串口与 arduino 和其他电子设备进行通信。
我需要启动一系列事件,以不同的时间调用不同的插槽,如下所示:
- 启动电机 1 20 秒
- 10 秒后启动电机 2
- 停止电机 1
- 更改电机 1 速度
- 启动电机 1 30 秒
我试过 QTimer::singleShot 但它只适用于没有参数的插槽,我需要不时设置不同的参数,例如电机速度。
现在我正在使用一个延迟函数来对抗 currentTime do dieTime,但是跟踪所有设备的时间很复杂。
这样做的最佳解决方案是什么?
建议?
使用overloaded method, which takes a Functor (function object). This would allow you to capture the variables required; which motor, speed, action etc. If you're not familiar with Functors, you can read about them here即可使用静态QTimer单发功能。
或者,由于问题没有提供代码示例,我们假设您已经编写了用于启动和停止电机的函数。对于更直接的方法,with C++11,你可以这样做:
StartMotor(1);
// Stop in 20 seconds
QTimer* p1 = new QTimer;
connect(p1, &QTimer::timeout, [=]{
StopMotor(1);
p1->deleteLater(); // clean up
});
p1->start(1000 * 20); // trigger in 20 seconds
// After 10 seconds, start motor 2
QTimer* p2 = new QTimer;
connect(p2, &QTimer::timeout, [=]{
StartMotor(2);
// And Stop Motor 1
StopMotor(1);
p2->deleteLater(); // clean up
});
p2->start(1000 * 10); // trigger in 10 seconds
...每个定时动作依此类推。
为电机实施 class 例如:
class Motor:public QObject
{
Q_OBJECT
public slots:
void start();
void start(int ms); //this one starts QTimer::singleShot and calls stop
void stop();
};
我建议检查 QStateMachine 框架。
当任务变得更加复杂时,最好使用 FSM 而不是意大利面条式的信号槽调用。
在我当前的项目中,我构建了一个基于 QStateMachine 的 FSM,其中 FSM 的定义是在 DSL(领域特定语言)中完成的。
我正在用 Qt/c++ 编写一个软件,通过串口与 arduino 和其他电子设备进行通信。
我需要启动一系列事件,以不同的时间调用不同的插槽,如下所示:
- 启动电机 1 20 秒
- 10 秒后启动电机 2
- 停止电机 1
- 更改电机 1 速度
- 启动电机 1 30 秒
我试过 QTimer::singleShot 但它只适用于没有参数的插槽,我需要不时设置不同的参数,例如电机速度。
现在我正在使用一个延迟函数来对抗 currentTime do dieTime,但是跟踪所有设备的时间很复杂。
这样做的最佳解决方案是什么? 建议?
使用overloaded method, which takes a Functor (function object). This would allow you to capture the variables required; which motor, speed, action etc. If you're not familiar with Functors, you can read about them here即可使用静态QTimer单发功能。
或者,由于问题没有提供代码示例,我们假设您已经编写了用于启动和停止电机的函数。对于更直接的方法,with C++11,你可以这样做:
StartMotor(1);
// Stop in 20 seconds
QTimer* p1 = new QTimer;
connect(p1, &QTimer::timeout, [=]{
StopMotor(1);
p1->deleteLater(); // clean up
});
p1->start(1000 * 20); // trigger in 20 seconds
// After 10 seconds, start motor 2
QTimer* p2 = new QTimer;
connect(p2, &QTimer::timeout, [=]{
StartMotor(2);
// And Stop Motor 1
StopMotor(1);
p2->deleteLater(); // clean up
});
p2->start(1000 * 10); // trigger in 10 seconds
...每个定时动作依此类推。
为电机实施 class 例如:
class Motor:public QObject
{
Q_OBJECT
public slots:
void start();
void start(int ms); //this one starts QTimer::singleShot and calls stop
void stop();
};
我建议检查 QStateMachine 框架。 当任务变得更加复杂时,最好使用 FSM 而不是意大利面条式的信号槽调用。
在我当前的项目中,我构建了一个基于 QStateMachine 的 FSM,其中 FSM 的定义是在 DSL(领域特定语言)中完成的。