Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

Make GUI main() thread responsive when Qthread is running



  • Hi,

    i am trying to update my GUI when QThread is still running.
    Inside run():

    QProcess *process = new QProcess();
    process->setWorkingDirectory(QString(getenv("TEMP"))+"\Felix");
    process->start(""" + ansysPath1 + "" -b -i get_node_results.mac -o output.out");
    process->waitForFinished(-1);

    in mainwindow:

    FelixThread *ansysThread = new FelixThread(tempDirPath,ansysPath,felixMutex);
    ansysThread->start();
    qApp->processEvents(QEventLoop::ExcludeUserInputEvents);
    ansysThread->wait();

    the ansysthread will take more time, i even tried to get finished() signal of the thread, but on using finished() emits before the qthread finished executing the script inside run(). Any suggestion how to approach this??



  • Hi @meganathan,

    QProcess starts processes asynchronously, so no need to use QThread.
    Instead try something like this (in mainwindow):

    QProcess *process = new QProcess(this);
    process->setWorkingDirectory(QString(getenv("TEMP"))+"\Felix");
    
    // you can connect the finished signal of process to a lambda like this, or by using a slot.
     
    connect(process, QOverload<int, QProcess::ExitStatus>::of(&QProcess::finished),
        [=](int exitCode, QProcess::ExitStatus exitStatus)
            {
                 /* here you can handle the finished state of your process */
            });
    	
    process->start(""" + ansysPath1 + "" -b -i get_node_results.mac -o output.out");
    

    As I said, use this code inside mainwindow (GUI thread), and it's not going to block anything. QProcess is designed to work asynchronously and synchronously (waitForFinished()). In your case you must use its signals, instead of its synchronous API
    .



  • Hi @SamurayH ,

    i am using Qt 4.8 ,does it support
    connect(process, QOverload<int, QProcess::ExitStatus>::of(&QProcess::finished),
    [=](int exitCode, QProcess::ExitStatus exitStatus)
    {
    /* here you can handle the finished state of your process */
    });

    i made it like this
    connect(process,SIGNAL(finished(int,QProcess::ExitStatus)),this,SLOT(onQProcessFinish(int,QProcess::ExitStatus))); //in constructor

    finished sigmal is not emitting..do i need to use QEventloop to block the Qprocess->start() to complete the Qprocess.


  • Lifetime Qt Champion

    Hi,

    You should also check for errors with QProcess.



  • @SGaist
    Hi,
    connect(process,SIGNAL(finished(int,QProcess::ExitStatus)),this,SLOT(onQProcessFinish(int,QProcess::ExitStatus)))
    connect(process,SIGNAL(error()),this,SLOT(onQProcessFailure()));

    Both are in constructor of mainwindow. both the signal are not emitting



  • @meganathan,

    Make sure you're connecting the signals before calling start.



  • @SamurayH On using finished() signal to emit, will the main thread wait until finished() completes the execution.
    Because i need to work on the task based on files generated by scripts.


  • Lifetime Qt Champion

    No, the idea is that the code you want call once your process has finished is in the slot you connect to the finished signal.


Log in to reply