PDA

View Full Version : QProcess emits readyRead too late!



dynup
23rd March 2015, 13:47
Hi,

I wrote an appliaction for Android Debug Bridge (adb) to backup app data from an android device. But QProcess doesn't emit readRead signal, although adb gives an output:

class.h:


QProcess *process;

class.cpp:

process = new QProcess(this);
connect(process, SIGNAL(readyRead()), this, SLOT(readyRead()));
connect(process, SIGNAL(finished(int, QProcess::ExitStatus)), this, SLOT(finished(int, QProcess::ExitStatus)));

process->start("adb", QStringList() << "blah", QProcess::ReadOnly);

(...)


void Class::readyRead() {
qDebug() << "Class::readyRead()";
}

In terminal the message is coming, than i confirm it on the device and than it's done. In QProcess the readRead signal is emitted after confirming on device! Why?

Thanks!

P.S.


connect(process, SIGNAL(readyReadStandardOutput), this, SLOT(readyRead()));

or


process->start("adb", QStringList() << "blah", QProcess::ReadOnly | QIODevice::Text | QIODevice::Unbuffered);

doesn't work too!

wysota
23rd March 2015, 14:14
Do you let your application process events often enough?

dynup
23rd March 2015, 15:51
Will QProcess (adb) not running in a separate thread?

jefftee
23rd March 2015, 15:55
It will run in a separate process, not a separate thread. Are you using any of the QProcess::waitFor* methods by chance?

Edit: I don't use Qt for Android, so perhaps the terminology process and thread are the same, I just don't know. :)

yeye_olive
23rd March 2015, 17:00
@dynup

Do not confuse the external process managed by the QProcess object with the thread in which this object lives. The QProcess object can only emit its readyRead() signal if the thread in which it lives processes its events. For instance, a minimal program could look like:



int main(int argc, char **argv) {
QCoreApplication app(argc, argv);
...
QProcess p;
MyObject o;
...
connect(&p, SIGNAL(readyRead()), &o, SLOT(readAvailableDataAndDoSomethingWithIt()));
p.start(...);
// At this point, the external process may have started, but we are not yet handling any events; in particular, we will not pick up the notifications sent by the OS when the process writes to its output, and p will not emit readyRead()
...
return app.exec(); // This starts the event loop; p will emit readyRead() when appropriate
}

dynup
23rd March 2015, 18:32
It will run in a separate process, not a separate thread. Are you using any of the QProcess::waitFor* methods by chance?
...with this methods the application freeze.


Edit: I don't use Qt for Android, so perhaps the terminology process and thread are the same, I just don't know. :)
It's not for Android, it's running on Linux!


Do not confuse the external process managed by the QProcess object with the thread in which this object lives. The QProcess object can only emit its readyRead() signal if the thread in which it lives processes its events.
Ok, but how can I do this?

yeye_olive
23rd March 2015, 18:42
Ok, but how can I do this?
Well, I showed how in my previous post. In the simple program I wrote, the line


app.exec();

runs the event loop and handles events until something asks it to quit. When the external process managed by p writes to its standard output, the OS notifies your program, the event loop picks this event, p emit readyRead(), and, thanks to the connection


connect(&p, SIGNAL(readyRead()), &o, SLOT(readAvailableDataAndDoSomethingWithIt()));

the slot o.readAvailableDataAndDoSomethingWithIt() is run.

You should read the Qt documentation about signals, slots, and event loops.