Search code examples
c++qtqtimer

C++ Timer difficulties


I'm having issues implementing timing. What i want to do is run this:

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

as while a button is pressed.

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

however, so far everything i've tried so far has been a failure.

What's the correct way to go about this?

Thanks


Solution

  • The task they want to implement is not blocking, so it is not necessary to use threads, only a timer with an adequate logic. To make it simple we will assign that task to the next 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
    

    Then an object is created and used in the slot pressed:

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