C++ 定时器困难

C++ Timer difficulties

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

//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.
    }
}

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

解决这个问题的正确方法是什么?

谢谢

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

relaycontroller.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

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

mainwindow.h

private:
    RelayController *controller;

mainwindow.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();
}