Unsolved Can't read output from Qt program using QProcess
-
I can't read anything produced by Qt program using the following code:
QString program = "C:/Users/jiang/QtDream/bin/TestConsoleOuput.exe"; QStringList arguments; QProcess* process = new QProcess( this ); process->setReadChannel( QProcess::StandardOutput ); process->setProcessChannelMode( QProcess::ForwardedOutputChannel ); connect( process, SIGNAL( readyRead( ) ), this, SLOT( read( ) ), Qt::DirectConnection ); connect( process, SIGNAL( finished( int, QProcess::ExitStatus ) ), this, SLOT( onProgramFinished( int, QProcess::ExitStatus ) ), Qt::DirectConnection ); process->start( program, arguments, QIODevice::ReadWrite ); void AnimatedSplash::readStandardOutput( void ) { QProcess* process = qobject_cast<QProcess*>( sender( ) ); qDebug( ) << process->readAllStandardOutput( ); qDebug( ) << "Come here."; } void AnimatedSplash::readStandardError( void ) { QProcess* process = qobject_cast<QProcess*>( sender( ) ); qDebug( ) << process->readAllStandardError( ); qDebug( ) << "Come here 2."; } void AnimatedSplash::read( void ) { QProcess* process = qobject_cast<QProcess*>( sender( ) ); qDebug( ) << process->readAll( ); qDebug( ) << "Come here 3."; } void AnimatedSplash::onProgramFinished( int exitCode, QProcess::ExitStatus exitStatus ) { Q_UNUSED( exitStatus ); qDebug( ) << "Program exited with code: " << exitCode; }
The code of
TestConsoleOutput
is:#include <QDebug> int main(int argc, char *argv[]) { qDebug( ) << "Do you remember it? "; return 0; }
I am quite confused by that.
-
@jiancaiyang said in Can't read output from Qt program using QProcess:
connect( process, SIGNAL( readyRead( ) ), this, SLOT( read( ) ), Qt::DirectConnection );
You're not using the functions you've defined.
connect( process, SIGNAL( readyRead( ) ), this, SLOT( read( ) ), Qt::DirectConnection );
Your
AnimatedSplash::read()
(if that's what yourread( )
is?) doesprocess->readAll( )
, not call your other methods. I would however expect that function to be hit?Your text program uses
qDebug( )
. Is that producing nothing because you're compiling for release?? -
@JonB Let me check. Indeed, I am using release version of my program.
-
@jiancaiyang
LOL. You must check output by running your program before you complain you're not receiving anything back :) -
@JonB Strangely, when compiled with debug symbols, and it doesn't show anything either.
The code:
#include <QtGlobal> int main(int argc, char *argv[]) { Q_UNUSED( argc ); Q_UNUSED( argv ); qInfo( "Do you remember it? " ); return 0; }
-
@JonB said in Can't read output from Qt program using QProcess:
connect( process, SIGNAL( readyRead( ) ),
this, SLOT( read( ) ), Qt::DirectConnection );AnimatedSplash::read()
function is shown above.You're not using the functions you've defined.
connect( process, SIGNAL( readyRead( ) ),
this, SLOT( read( ) ), Qt::DirectConnection );Your AnimatedSplash::read() (if that's what your read( ) is?) does process->readAll( ), not call your other methods. I would however expect that function to be hit?
-
@JonB Tested. It is reported that std funtions such as
printf()
works. Whereas Qt supported functions are not, I need to catch Qt debug output because our software is based on Qt. -
@jiancaiyang
You still have not confirmed whether your test program, run standalone outside Qt Creator, does or does not produce any output. If it does not, there is nothing for your parent to read!qDebug()
etc. probably write tostderr
notstdout
.If it does, then I do not use
QIODevice:readAll()
. The docs state that includes both stdout & stderr, but I don't know. I use the examples everywhere which use QProcess merged channels and/or both readStandardOutput() & readStandardError() with their corresponding signals. -
@JonB I tested.
The debug version of TestConsoleOutput.exe write message to stdout. but QProcess can't get it. -
Then like I said:
If it does, then I do not use QIODevice:readAll(). The docs state that includes both stdout & stderr, but I don't know. I use the examples everywhere which use QProcess merged channels and/or both readStandardOutput() & readStandardError() with their corresponding signals.
You use
QIODevice:readAll()
. I use explicit stdout/stderr functions, and they work fine for me for stdout & stderr. That's all I can say. Unless someone else wants to comment on why your code does not work as you expect. -
@JonB said in Can't read output from Qt program using QProcess:
I use explicit stdout/stderr functions, and they work fine for me for stdout & stderr
Agreed. But if there is a Qt program that uses qDebug, qWarning, etc. everywhere instead of printf, how could I read the information from console? I noticed that Qt Creator can better show the messages on application output panel.
-
@jiancaiyang
I am assuming thatqDebug()
writes tostderr
.That will show up fine in a console.
When it is executed in a sub-process launched through
QProcess
you must ensure you are correctly getting that sub-process'sstderr
channel. You are usingQIODevice::readAll()
(andQProcess::ForwardedOutputChannel
) to achieve that. I cannot say whether your approach works correctly as I do not use that way --- I use theQProcess
stdout/stderr &QProcess::MergedChannels
functions explicitly. Which work for me.Temporarily, change your
TestConsoleOutput
to:int main(int argc, char *argv[]) { printf("This is stdout\n"); fprintf(stderr, "This is stderr\n"); return 0; }
Now make sure your code gets both of those lines back successfully:
-
If it does not, you have a problem with stdout/stderr reading in the code approach you're doing.
-
If it does, you have a problem to do with
qDebug()
specifically.
-
-
@JonB Things different.
In your code, you only use
printf
to write to stdout
fprintf
to write to stderr
Thant worked for me too. But another software which is written by me uses only Qt related debugging techniques, more specifically, I only useqCDebug
,qCWarning
, etc. to write pretty logs.
The program which launches the software is called "daemon" program. At the beginning, I need to show our logo as a splash screen, then wait until the main program ( software ) launches. This comes to whether to communicate between processes ( IPC ). At present, I choose the easiest way, that is to read output from channel.I tried
printf
worked, I guessfprintf
worked too, but Qt's function does not work.
If we do this in Qt Creator like this:
Qt Creator could receive our software's debug output. I wonder why can't I use QProcess to do that.
-
@jiancaiyang
So you are saying:-
Testing with program known to write to stdout/stderr (e.g.
fprintf
) does work successfully with your sub-process & reading code. That means theQProcess
code you have looks good in itself. -
Running your program which actually spawns some sub-process which itself is written in Qt does not get any output back. You believe the sub-process Qt application is using
qDebug()
etc., and you'd like to get it.
If that's correct, what makes you think the sub-process (using
qDebug()
or not) is writing anything to stdout/stderr? If it's a Qt GUI app it won't write anything to those, I think(?). If you run that app from a console, do you get any output from it in the console you ran it from? If not, it's not writing to stdout/stderr!And if that's the case you'll have a hard time getting its
qDebug()
output... You'll need a Qt expert to tell you whether/how you can get at another Qt GUI app'sqDebug()
statements.I am of course assuming you've made sure your other app is indeed actually producing any
qDebug()
output, it's not compiled for release.... -
-
@JonB Yeah,
qDebug
,qInfo
,qWarning
is not turned off when developer switch to non-debug mode.A phenomenon, as noted by Qt doc, shows that GUI only applications does not show anything from console, In my practice, they seems to be detached by console window. you can view the notice:
Note: Windows intentionally suppresses output from GUI-only applications to inherited consoles. This does not apply to output redirected to files or pipes. To forward the output of GUI-only applications on the console nonetheless, you must use SeparateChannels and do the forwarding yourself by reading the output and writing it to the appropriate output channels.
An approach to tweak is to write my own message handler, which is referred as
QtMessageHandler qInstallMessageHandler(QtMessageHandler handler)
Then in my own implementation, write all info and debug messages to stdout, all warning and error messages to stderr.
But this is not a good idea because such function has been used for the software internally. I don't want to bother. -
@jiancaiyang
I don't believe "inherited consoles" is relevant here. Like I asked above:If you run that app [your app which you say goes
qDebug()
)] from a console, do you get any output from it in the console you ran it from? If not, it's not writing to stdout/stderr!?