Reputation: 211
In my Qt application, I have a push button to launch a job which takes ~10s to complete. I notice that during the 10s period after clicking the button, if I click in the button area again, it is still taken as a click and the job will be launched again as soon as it is concluded from the first click.
Is this expected? What can I do to avoid the button click until the job from the first click is concluded? Thanks.
Upvotes: 0
Views: 4337
Reputation: 211
After poking on it, I think the "QCoreApplication::processEvents()" does the trick. Here is what I find out, also as a conclusion to the subject:
=========================
void MainWindow::on_pushButton_2_clicked()
{
QDateTime dateTime;
qDebug()<<"Btn2-Time#1:"<<dateTime.currentDateTime().toString("[yyyyMMdd hh:mm:ss] ");
QThread::sleep(10);
qDebug()<<"Btn2-Time#2:"<<dateTime.currentDateTime().toString("[yyyyMMdd hh:mm:ss] ");
}
Originally my code is like above, and as I click the button and click again during the 10s sleep time, I get this and notice the 2nd run start immediately after the 1st run concluded.
Btn2-Time#1: "[20170731 16:07:39] "
Btn2-Time#2: "[20170731 16:07:49] "
Btn2-Time#1: "[20170731 16:07:49] "
Btn2-Time#2: "[20170731 16:07:59] "
=========================
void MainWindow::on_pushButton_clicked()
{
QDateTime dateTime;
ui->pushButton->setEnabled(false);
qDebug()<<"Btn1-Time#1:"<<dateTime.currentDateTime().toString("[yyyyMMdd hh:mm:ss] ");
QThread::sleep(10);
qDebug()<<"Btn1-Time#2:"<<dateTime.currentDateTime().toString("[yyyyMMdd hh:mm:ss] ");
QCoreApplication::processEvents();
ui->pushButton->setEnabled(true);
}
Following one of the comment, I added the disable and QCoreApplication::processEvents(); as above, now the same operation will not trigger the 2nd run, because the 2nd click is processed before the button is reset to enable.
Btn1-Time#1: "[20170731 16:07:24] "
Btn1-Time#2: "[20170731 16:07:34] "
=========================
void MainWindow::on_pushButton_3_clicked()
{
QDateTime dateTime;
ui->pushButton_3->setEnabled(false);
qDebug()<<"Btn3-Time#1:"<<dateTime.currentDateTime().toString("[yyyyMMdd hh:mm:ss] ");;
QThread::sleep(10);
qDebug()<<"Btn3-Time#2:"<<dateTime.currentDateTime().toString("[yyyyMMdd hh:mm:ss] ");
//QCoreApplication::processEvents();
ui->pushButton_3->setEnabled(true);
}
Commenting out the QCoreApplication::processEvents();, it processes the 2nd click as original, so just disabling the button isn't the solution, and the QCoreApplication::processEvents(); does the trick!
Btn3-Time#1: "[20170731 16:08:00] "
Btn3-Time#2: "[20170731 16:08:10] "
Btn3-Time#1: "[20170731 16:08:10] "
Btn3-Time#2: "[20170731 16:08:20] "
=========================
Thank you!
Upvotes: 1
Reputation: 844
I would disable the button until the job is completed and add a label (or GIF animation) to indicate the "work in progress". This is better for the user, as he sees that the button is disabled --> i.e. he has a "feedback" from your system. Then when the process is finished you emit a "finished" signal Signals and Slots, that is connected to an "enableButtons" slot --> i.e. After finishing the process you re-enalbe the button.
void Process(){
ui->yourButton->setEnabled(false);
/* Maybe play loading gif animation etc*/
/* Do your work here */
emit ProcessFinished();
}
Upvotes: 3
Reputation: 180
You can use the "setEnabled" and setDisabled" methods to deactivate the button when the job is exectued and then add a callback to activate the button when the job is complete.
Read the documentation for setEnabled here: http://doc.qt.io/qt-5/qwidget.html#enabled-prop
Upvotes: 0