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 your read( ) is?) does process->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 to stderr not stdout.

    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.
    0_1518184004013_7a5f390f-f466-44cb-9d30-298aaa9d39bd-image.png 0_1518184004090_47d709ea-0551-41c3-a0bf-c0da011f8e71-image.png
    The debug version of TestConsoleOutput.exe write message to stdout. but QProcess can't get it.



  • @jiancaiyang

    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 that qDebug() writes to stderr.

    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's stderr channel. You are using QIODevice::readAll() (and QProcess::ForwardedOutputChannel) to achieve that. I cannot say whether your approach works correctly as I do not use that way --- I use the QProcess 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 use qCDebug, 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 guess fprintf worked too, but Qt's function does not work.
    If we do this in Qt Creator like this:
    0_1518189130233_0727615f-f1c1-4b06-ab13-f5671bbc0b15-image.png

    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 the QProcess 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's qDebug() 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!

    ?


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.