How to have a timer in main.cpp in qt creator to update the GUI when a button is clicked?

532 Views Asked by At

I am creating a laundry machine simulation with my team for school. I have simulation.cpp where I have functions to control the GUI and main.cpp where I only call one Work() function which is supposed to check whether the user has clicked on a button (e.g. adding coins). There are many classes and interfaces in between these two which handles the application logic which do not matter for the simulation part.

My problem is that I want to be able to check a checkbox when a button is clicked. However, in main.cpp I cannot do anything after return a.exec(). I also cannot do anything before that since this is what pops up the GUI.

So I want to use a timer with 1 sec interval, which when ticks calls the Work() function. I created this timer in simulation.cpp which works but I could not create it in main.cpp.

My simulation.cpp looks like this:

bool button10 = false;
Simulation::Simulation(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::Simulation)
{
    ui->setupUi(this);
    timer = new QTimer(this); // create it
        connect(timer, &QTimer::timeout, this, &Simulation::TimerSlot ); // connect it

    timer->start(1000);
}

void Simulation::TimerSlot()
{
    SetCoin_10(coin10); 
    coin10++;
}
void Simulation::SetCoin_10(uint8_t nrOfCoins){
    if(nrOfCoins == 1){
        ui->checkBox_17->setChecked(1);
    }
    else if(nrOfCoins ==2){
        ui->checkBox_16->setChecked(1);
    }
    else if(nrOfCoins ==3){
        ui->checkBox_15->setChecked(1);
    }
}

uint8_t Simulation::GetBtn_10(){
    if(button10){
        button10 = false;
        return true;
    }
    else{
        return false;
    }
}

and main.cpp:

int main(int argc, char *argv[])
{

    QApplication a(argc, argv);
    
    simulation = new Simulation();
    
    cs = new Coins(simulation);
     ps = new ProgramSelector(simulation);
     sp = new Soap(simulation);
     dr = new Director(cs, ps, sp);

    simulation->show();
    dr->Work(); //this is what I want to execute every second (from director class)
    return a.exec();

}

How do I make this happen? Thanks a lot in advance!

1

There are 1 best solutions below

0
On BEST ANSWER

You can "connect" to Events. Qt will enter the event loop on exec() and call the connected functions when events occur.

You already did that on your timer. You just call the TimerSlot() whenever the timer fires.

Your problem is just the accessibility of your variables. Right now, you cannot access "dr" to call "dr->Work()" from within the simulation class.

Option1:

Pass the objects like "dr" and "cs" to the Simulation, either in Constructor like new Simulation(dr, cs...) or by adding setter function that you then call like simulation.setCoins(cs)

Option2:

Create the objects like "dr" and "cs" in the Simulation. Probably best in constructor.


Hint: For both options, you should probably create member variables like this:

private Coins coins;

This will not require new keyword, because it's created on the stack instead of the heap. This also means, you don't need to delete the coins object in destructor. As you don't get a pointer then, you access functions using . instead of ->.