C++ 计时器困难

C++ Timer difficulties

本文关键字:计时器 C++      更新时间:2023-10-16

我在实现计时时遇到问题。我想做的是运行这个:

//relay 1 power cycle
void MainWindow::relay1PCycle()
{
    relay1High();
    while (true){
        QTimer::singleShot(750, this, SLOT(relay1Low()));
        QTimer::singleShot(750, this, SLOT(relay1High()));
    }
}

就像按下按钮时一样。

//power cycle button
void MainWindow::on_pushButton_3_toggled(bool checked)
{
    if (checked){
        //run relay1PCycle as a thread.
    }
    else{
        //Terminate relay1PCycle thread.
    }
}

然而,到目前为止,我尝试的一切都失败了。

正确的

方法是什么?

谢谢

他们想要实现的任务不是阻塞,所以没有必要使用线程,只需要一个具有足够逻辑的计时器。为了简单起见,我们将该任务分配给下一个类:

继电器控制器.h

#ifndef RELAYCONTROLLER_H
#define RELAYCONTROLLER_H
#include <QObject>
#include <QTimer>
#include <QDebug>
class RelayController : public QObject
{
    Q_OBJECT
public:
    explicit RelayController(QObject *parent = 0):QObject(parent){
        timer = new QTimer(this);
        state = false;
        timer->setInterval(750);
        //old style
        connect(timer, SIGNAL(timeout()), this, SLOT(onTimeout()));
        //new style
        //connect(timer, &QTimer::timeout, this, &RelayController::onTimeout);
    }
    void start(){
        qDebug()<<"timer";
        timer->start();
    }
    void stop(){
        timer->stop();
    }
    void relayLow(){
        //code here: relay off
        qDebug()<<"low";
    }
    void relayHigh(){
        //code here: relay on
        qDebug()<<"high";
    }
private slots:
    void onTimeout(){
        if(state)
            relayHigh();
        else
            relayLow();
        state = !state;
    }
private:
    QTimer *timer;
    bool state;
};
#endif // RELAYCONTROLLER_H

然后在按下的插槽中创建一个对象并使用:

主窗口.h

private:
    RelayController *controller;

主窗口.cpp

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    controller = new RelayController(this);
    ui->pushButton_3->setCheckable(true);
}
void MainWindow::on_pushButton_toggled(bool checked)
{
    if(checked)
        controller->start();
    else
        controller->stop();
}