Search code examples
qtwidgetqpushbutton

QT push button / stop button


I have a push button that I'd like to change to a stop button when clicked. Currently the button's text says "auto fire", it runs an endless loop and it's text changes to "stop auto fire" when clicked. My problem is breaking the endless loop by clicking/pressing this button again after the text changes.

Code so far:

void Cpp_Fire::on_auto_fire_clicked()
{
    while(true)
    {
        ui->auto_fire->setText("Stop Auto Fire");
        on_manual_fire_clicked();
    }
}

I tried inserting a different slot into the loop above that runs when after the button is pressed (it runs when the button is released to be precise) but I couldn't get it to work. I know this could be done with signals/slots and a separate stop button but I'm unfamiliar with that method and I prefer the method I described.


Solution

  • The problem with your endless loop is that nothing else gets a chance to work.

    One approach you could use is to use a QTimer with a short interval to call the on_manual_fire_clicked() method, then have the on_auto_fire_clicked() method be responsible for changing the text on the button and enabling / disabling the timer.

    The ui should get enough time to respond to clicks etc if you do it that way.

    edit:

    For more info on using QTimer have a look at this page:

    How to use QTimer

    or this tutorial:

    http://www.bogotobogo.com/Qt/Qt5_QTimer.php

    Here's some code:

    mainwindow.h

    #ifndef MAINWINDOW_H
    #define MAINWINDOW_H
    #include <QMainWindow>
    
    namespace Ui {
    class MainWindow;
    }
    
    class MainWindow : public QMainWindow
    {
        Q_OBJECT
    
    public:
        explicit MainWindow(QWidget *parent = 0);
        ~MainWindow();
    
    private slots:
        void on_pushButton_clicked();
        void timerslot();
    
    private:
        Ui::MainWindow *ui;
    
        QTimer* myTimer;
    };
    
    #endif // MAINWINDOW_H
    

    mainwindow.cpp

    #include "mainwindow.h"
    #include "ui_mainwindow.h"
    #include<QTimer>
    #include<QDebug>
    
    MainWindow::MainWindow(QWidget *parent) :
        QMainWindow(parent),
        ui(new Ui::MainWindow)
    {
        ui->setupUi(this);
    
        myTimer = new QTimer(this);
        myTimer->setInterval(500);
        myTimer->setSingleShot(false);
        connect(myTimer, SIGNAL(timeout()), this, SLOT(timerslot()));
        myTimer->start();
    }
    
    MainWindow::~MainWindow()
    {
        delete ui;
    }
    
    void MainWindow::timerslot()
    {
        qDebug() << "timeslot";
    }
    
    void MainWindow::on_pushButton_clicked()
    {
        if ( this->myTimer->isActive() == true ) {
            this->myTimer->stop();
            ui->pushButton->setText("Start");
        } else {
            this->myTimer->start(500);
            ui->pushButton->setText("Stop");
        }
    }
    

    I hope you get the idea and can convert it to your needs.