Unsolved QProcess finish signal not emitted.
-
@SGaist said in QProcess finish signal not emitted.:
Hi and welcome to devnet,
What exactly are you executing ?
Can you show the full code related to QProcess ?Basically this:
procc = new QProcess();connect(procc, QOverload<int, QProcess::ExitStatus>::of(&QProcess::finished), [=](int exitCode, QProcess::ExitStatus exitStatus) { std::cout<<"DEBUG"<<std::endl; this->handle_finished(exitCode); });
procc->start(appname.c_str());
Now, I just discovered something.. weird. If I call waitForStarted().. it goes immediately into running state (otherwise it stays stuck in starting.. forever even after the process ends).
but it does never reach not_running state, unless I waitForFinished()
It seems the problem is not in the signals but in Qt keeping track of the state correctly. As far as I understood the documentation I should be able to start the process. NOT call waitForFinished() and expect the state of the QProccess to still be updated to the correct values. Am I wrong?
-
What application are you trying to start that has issues ?
-
Are you blocking the eventloop somehow?
-
@SGaist
You know more than I, but I don't think the process he runs is at issue. I believe it itself runs fine. The issue, I think, lies in the use of threads, or where the event loop is allowed to run so the status is updated, signals are delivered, etc. ThewaitFor...()
spins its own loop and works. No? -
@SGaist I have tried even a helloworld program. Simple basic std::cout<<"Hello World" <<std::endl; return 0 at main. My objective is to tun another application that I made with Qt, but when I started to face the problem I decided to try with an application as simple as possible to help detect what is wrong.
@Christian-Ehrlicher nope. The events from my interface work correctly, all clicks, released etc events are handled perfectly even while the process that I started is running, so I figure the event Loop must be working.
I can reproduce the same issue by creating the minimal QtWidget program with QtCreator and with the following main.cpp
#include "mainwindow.h"
#include <QApplication>
#include <QProcess>
#include <thread>
#include <iostream>int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MainWindow w;
w.show();std::thread* ptr = new std::thread([]() { std::this_thread::sleep_for(std::chrono::seconds(5)); QProcess proc; proc.start("/tmp/batata"); while(proc.state()!=QProcess::NotRunning) std::cout<<" waiting:"<<proc.state()<<std::endl; std::cout<<"DONE"<<std::endl; }) ; auto execresult= a.exec(); ptr->join(); delete ptr; return execresult;
}
the process state stays stuck at 1.. forever.. the program at /tmp/batata just writes linesin a file for 10 seconds and then exits... but even after it finishes the state is stuck at 1.
I must be missing something here. Even by this simple example the QProcess is created and started quite after the QApplication exec starts (the sleep is there to ensure it).
-
@TiagoSD said in QProcess finish signal not emitted.:
while(proc.state()!=QProcess::NotRunning) std::cout<<" waiting:"<<proc.state()<<std::endl;
But this blocks, how will state get updated? Or finish get emitted?
BTW: are you (trying to) use threads because of wanting to run a process, not block, and be notified of finish? Because with
QProcess
and Qt it's asynchronous, you get that without needing threads. -
@JonB It is bocking a different thread.. not the Qt one.
I need to use threads for other purposes, the start of the application is not bound to the GUI , but to external events that are waited by a different thread (so when the external event happens I start the QProces.
I
-
As I guessed - there is no eventloop in the thread where QProcess lives.
No thread is needed at all for this task, and when then use QThread and run an eventloop. -
@Christian-Ehrlicher Ok, the problem is that the thread that I pass the lambda (that creaes the QProcess) is created by another library (not mine but i need to use it). So I will have to use somethign other than QProcess to handle this.
Thanks for the help anyway.
-
Then emit a signal there and move to a QThread with an eventloop or use QEventLoop directly.