lundi 17 juillet 2017

Running a QT MainWindow method on a separate thread

I am writing a C++ QT5 Widget Desktop Application and I need to run a time consuming operation MainWindow::performLengthyOperation(bool) on a separate thread when a start/stop button is pressed.

This time consuming operation is a rather lengthy method in my MainWindow.h/cpp. The operation to stop the background IO activity takes about 6 seconds and to start it takes about 2 seconds. During the time the start/stop button is pressed, the UI is non responsive. Essentially, in the slot attached to my button click event I need to perform the following logic.

void
MainWindow::on_pushButtonStart_clicked(bool checked)
{
    // temporarily disable the pushbutton 
    // until the lengthy operation completes
    mUI->pushButtonStart->setEnabled(false);

    if (checked) {
        // Start the timer tick callback
        mTickTimer.start(APP_TICK, this);
        mUI->pushButtonStart->setText("starting...");

        // This method needs to somehow run in its own QT thread
        // and when finished, call a slot in this MainWindow to
        // re-enable the pushButtonStart and change the statusBar
        // to indicate "runing..."
        performLengthyOperation(true);
        //mUI->pushButtonStart->setText("Stop")
        //mUI->statusBar->setStyleSheet("color: blue");
        //mUI->statusBar->showMessage("runing...");
    } else { // Stop the protocol threads
        // Stop the subsystem protocol tick timer
        mTickTimer.stop();
        mUI->pushButtonStart->setText("stopping...");
        // This method needs to somehow run in its own QT thread
        // and when finished, call a slot in this MainWindow to
        // re-enable the pushButtonStart and change the statusBar
        // to indicate "ready..."
        performLengthyOperation(false);
        // finally toggle the UI controls
        //mUI->pushButtonStart->setText("Start")
        //mUI->statusBar->setStyleSheet("color: blue");
        //mUI->statusBar->showMessage("ready...");
    }
}

When I was looking for examples on how to do this I came across the following article but I am having trouble adapting it to my scenario as I need to somehow get the MainWindow into the worker so it can access its UI widgets etc and that seems like a bit of overkill.

I am ideally looking for a simple way to asynchronously run a lambda function where I could place these time consuming operations (passing in the mainwindow as a parameter). That would be preferable to using QThreads and moving objects to threads etc. But I don't know enough about the QT framework to know if this is a safe or possible thing to do.

Aucun commentaire:

Enregistrer un commentaire