0

I'm calling a function on QMainWindow's constructor via QtConcurrent in hope that the GUI will be up and showing while the background IO bound task will be processing in the background:

MainWindow.h

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QtConcurrent>
#include <QFuture>

QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACE

class MainWindow: public QMainWindow
{
    Q_OBJECT

public:
    MainWindow(QWidget *parent = nullptr);
    ~MainWindow();
private:
    Ui::MainWindow *ui;
    int init();
};
#endif

MainWindow.cpp

MainWindow::MainWindow(QWidget *parent):QMainWindow(parent),ui(new MainWindow){
    ui->setupUi(this);
    ui->myLabel->setText("");
    ui->progress->setVisible(false);
    QFuture<int>future=QtConcurrent::run(MainWindow::init,this);
    if(future.result()==0){
        qInfo()<<"Init successful";
    }else{
        qInfo()<<"Init not successful";
    }
}

int MainWindow::init(){
    QThread::sleep(4);    //simulate IO task
    return 0;
}

But the GUI doesn't appear until init finishes. How to detach this pooled thread with main thread? Or from where should I run this thread?

EDIT: added QFutureWatcher to constructor but I don't know how to pass the return value of init to another function done:

MainWindow::MainWindow(QWidget *parent):QMainWindow(parent),ui(new MainWindow){
    ui->setupUi(this);
    ui->myLabel->setText("");
    ui->progress->setVisible(false);
    QFutureWatcher<int> watcher;
    QFuture future;
    connect(&watcher,QFutureWatcher<int>::finished,this,done(future.result())));//wrong code; need help here    
    future=QtConcurrent::run(MainWindow::init,this);
}

int MainWindow::init(){
    QThread::sleep(4);    //simulate IO task
    return 0;
}
void done(int val){
    if(val==0){
        qInfo()<<"Init successful";
    }else{
        qInfo()<<"Init not successful";
    }
}
JavaUser
  • 19
  • 3
  • 3
    Don't call `future.result()` from within the `MainWindow` constructor, since `result()` will block and not return until after the asynchronous routine has finished executing. https://doc.qt.io/qt-5/qfuture.html#result – Jeremy Friesner Jan 05 '23 at 06:37
  • If you want your GUI thread to get notified when `init()` has completed (so that you can call `result()` on the `QFuture` at that time and not have the call block), you can use a QFutureWatcher to emit a signal and call a slot-method of your choice when `init()` is done: https://doc.qt.io/qt-5/qfuturewatcher.html – Jeremy Friesner Jan 05 '23 at 06:41
  • @JeremyFriesner I've looked at the QFutureWatcher, and I'm confused at the part where `connect` is emitting `finished` signal. In the connect, I want the slot to get a value returned by my `init` and then proceed depending on that return value (0=successful, 1=error). – JavaUser Jan 05 '23 at 08:57
  • 1
    your slot-method can call `result()` on the `QFuture` object to get the value returned by `init`. Note that you'll need to make the `QFuture` into a member-variable rather than a local-variable so that it will be available for the slot-method to access. – Jeremy Friesner Jan 05 '23 at 15:02

0 Answers0