Search code examples
c++qttimerslotqtimer

Qt: is there any way to call a sequence of slots with certain time interval?


The way I am working now is to connect a QTimer to the first slot, inside the first slot it will trigger another single-shot QTimer which will trigger the second slot... and so on.

If I update all of the widgets at once, the GUI will stuck for a flash of a second. But it is noticeable. So I want to avoid that.

But this is very difficult to write code. You have to add QTimer everywhere. Are there any better solutions?

EDIT: This is how I update my widget, maybe there is better way?

void UAVInfoView::updateDisplay()
{

    if (!visibleRegion().isEmpty()){
        info = _dataSrc->getUAVInfo(_id-1);
        if (info)
        {
            //if new package received try to do updating.
            if (_pakchk != info->_pakcnt){
                //only update the text if there is communication
                if (info->_communication != COMMSTATUS::WAIT4CONNECTION && info->_communication != COMMSTATUS::LOST)
                {
                    ui->plainTextEdit->setPlainText(tr("x: %1\ny: %2\nz: %3").arg(info->_pos[0]).arg(info->_pos[1]).arg(info->_pos[2]));
                }
                //only update the status indicator only if status changed.
                if (_status != info->_communication)
                {
                    switch (info->_communication){
                    case COMMSTATUS::CONNECTED:
                        ui->groupBox->setStyleSheet("QGroupBox#groupBox {background-color:green;}");
                        ui->label_2->setText("On Line");
                        break;
                    case COMMSTATUS::LOST:
                        ui->groupBox->setStyleSheet("QGroupBox#groupBox {background-color:red;}");
                        ui->label_2->setText("Lost");
                        break;
                    case COMMSTATUS::WAIT4CONNECTION:
                        ui->groupBox->setStyleSheet("QGroupBox#groupBox {background-color:grey;}");
                        ui->label_2->setText("Off Line");
                    }
                }
            }
            //update the status and package counter to serve the state machine.
            _status = info->_communication;
            _pakchk = info->_pakcnt;
        }
    }
}

As you can see, it is just a bunch of default =, ! if else things...


Solution

  • You can call them in a slot connected to a timer with a certain interval. Your slot that is connected to the timer could be like :

    void myClass::onTriggered()
    {
        switch(turn){
           case 0:   
               slot1();
               break;
           case 1:
               slot2();
               break;
           ...
        }
    
        turn++;
        if(turn>=numberOfSlots)
            turn = 0;
    }
    

    This way each time one slot is called and they are called sequentially.