PDA

View Full Version : Disable Buttons during long operation.



davethomaspilot
11th August 2014, 00:23
Saving a .png takes a long time on the humble hardware. While it's being saved, I don't want the buttons to accept clicks.

I do QPushbutton::setEnabled(false) on them. They go grey, but if I click on them the click is accepted and processed after the long operation completes.

Is this expected behavior? Do I need to disconnect the signals and reconnect or is there a better way to disable clicks during a long operation?

It's Ok to block the GUI, that's what I want. I don't want the user to do anything until the operation completes.

(The windowModality is ApplicationModal and a ProgressBar is displayed also.)

Thanks,

Dave Thomas

ChrisW67
11th August 2014, 03:28
I do QPushbutton::setEnabled(false) on them.
That's how you do it.

They go grey, but if I click on them the click is accepted and processed after the long operation completes.
The button simply cannot be clicked and cannot execute any slot attached to it when not enabled. Something else is going on here.

Try this small example. Click the button multiple times while the process is running and note it does not start another run.


#include <QApplication>
#include <QPushButton>
#include <QTimer>
#include <QEventLoop>

class Button: public QPushButton
{
Q_OBJECT
public:
Button(QWidget *p = 0): QPushButton(p) {
setText("Push to Start");
connect(this, SIGNAL(clicked()), SLOT(start()));
}
public slots:
void start() {
static int count = 1;
setEnabled(false);
setText(QString("Run number %0 ...").arg(count++));

// A fake 5 second long task that keeps the UI alive.
QEventLoop loop;
for (int i = 0; i < 50; ++i) {
QTimer::singleShot(100, &loop, SLOT(quit()));
loop.exec();
qApp->processEvents();
}

setText("Push to Start");
setEnabled(true);
}
};

int main(int argc, char **argv)
{
QApplication app(argc, argv);
Button b;
b.show();
return app.exec();
}
#include "main.moc"



Afterthought: If you have connected the same button more than once then the first click will execute the slot more than once. Additional clicks while the button is disabled will not add to this.

davethomaspilot
11th August 2014, 16:48
I'll try the example, but it sure seems like a click on a pushbutton when it's disabled is "remembered" and executes the associated slot when the button is enabled.

Here's the code fragment:



QString filename = crn + "_" + dogName + "_" + QString::number(imageSuffix) + ".png";
filename.replace(QRegExp("[<>:\"/\\|?*]"), "");

pb->setWindowModality(Qt::ApplicationModal);
pb->setVisible(true);
//pb->show() ;
ui->Accept->setEnabled(false);
ui->Freeze->setEnabled(false);
ui->Reject->setEnabled(false);

QApplication::processEvents();

bool success = stillImage.save(imageDirectory + filename) ;



if (!success )
{
qDebug() << "something went wrong";
}
qDebug() << imageDirectory + filename;
qDebug() << crn;
qDebug()<< filename;

QSqlQuery qry;
qry.prepare("INSERT INTO title_pictures (crn,file_name) "
"VALUES( :crn, :file_name);" );

qry.bindValue(":crn", crn);
qry.bindValue(":file_name", filename);

int rows_affected = SqlUtils::exec_query(qry,false,false);
qDebug() << rows_affected;

// Save the image here.
settings.setValue("image_suffix",imageSuffix++) ;

emit startCapture(true);

pb->setVisible(false);
//pb->hide() ;
ui->Accept->setEnabled(true);
ui->Freeze->setEnabled(true);
ui->Reject->setEnabled(true);



pb is a QProgressBar *. The long operation is the stillImage.save() (saving a QPixmap). If I click on buttons during the five second save (they are greyed out), the slot code gets executed.

Platform is raspbian.

Dave Thomas