QProcess not reading stdout



  • I have an issue with getting a qprocess to read from a programs stdout channel. I've tried envoking waitforfinished, and I've also tried running it asynchronously (as below) like a separate qprocess I have that runs and returns fine. I've merged the stdout/err channels. The program launched by qprocess at the most basic level is a C program that interprets a string intput by the user, and outputs to stdout if the string contains certain elements. I've made sure in the external program to print via fprinf and tried fflush to get the channel to emit, but regardless of what I do my qprocess never receives the read ready signal.
    Some relevant experts are shown below:

      QString command_to_send="./../../../../ground_control/backend/bin/gc_prompt " + command;
        commanding=new QProcess(this);
                commanding->setProcessChannelMode(QProcess::MergedChannels);
                connect(commanding,SIGNAL(readyReadStandardOutput()),this,SLOT(gc_prompt_return()));
                commanding->start(command_to_send);
    
        //Display the command in the prompt window.
    
        QString prompt_out=cmd_time+" PROMPT: "+command;
        ui->cmd_txt_messages->append(prompt_out);
    ...
    void MainWindow::gc_prompt_return()
    {
        QString rtn_time=QTime::currentTime().toString();
        QString output=commanding->readAllStandardOutput();
        //Check for commanding error
        bool is_cmd_error;
        is_cmd_error=output.contains("ERROR");
        if (is_cmd_error) //check if a commanding error exists
        {
            //If there is a command interpreter error
        ui->cmd_txt_messages->setTextColor(Qt::red);
        ui->cmd_txt_messages->append(rtn_time+": "+output); //update prompt with red text
        ui->cmd_txt_messages->setTextColor(Qt::black);
        }
        else
        {
            //if the command is valid or the interpreter returned no error
            ui->cmd_txt_messages->append(output); //update prompt with black text
            ui->cmd_txt_messages->append(output);
        }
    
    ...
    private:
        Ui::MainWindow *ui;
        //Make pointer for telemetry listener
        QProcess *listeners;
            //Pointers for sim connection processes
        QProcess *tlm_reader;
        QProcess *commanding;
    

    edit: The qprocess seems to signal when stdout is written from the external program's main(), but the support functions it calls won't print. marco_cmd should have outputs to stdout, and displays when called directly in a terminal, but qt doesn't catch the output when launched as a qprocess, the error statement at the end always prints fine regardless of what I do.
    Program called by qprocess:

        // Check to see if macro is "cmd":
        if (strcmp("cmd",input_str_arr[0]) == 0){
            // Start command macro function:
            macro_cmd(input_str_arr);
    
            // Exit:
            fflush(stdout);
            return;
        } 
    
        // If you get here, the macro is not recognized:
        printf("(PROMPT_INTERP) <ERROR> \"%s\" macro not recognized\n",\
            input_str_arr[0]);
    
        // Exit:
        return;
    

  • Lifetime Qt Champion

    Hi and welcome to devnet,

    You should connect the errorOccured signal.

    You are also not checking the exit code value.



  • After checking errorOccured, it's returning "crashed", since it looks like in the C program exit() is called from a child process. After further research, it looks like the reason Qt isn't reading the stdout is because the printf statements are in child processes and are not piped back to main. In the future, if you're hoping to read stdout from an external program, you need pipes back to the parent in order read it in Qt, even if the statements are output to the terminal. Marking resolved.



  • @CaffeinatedGecko
    Glad you are resolved.

    However, for anyone else reading this in the future. QProcess correctly reads from a child process's stdout. Plenty of programs use this. I do not know what your particular sub-process is doing wrt its printf()s or whatever. It would not catch something sent explicitly to a console. I would have thought in this case

    it's returning "crashed",

    might be relevant.



  • @JonB Thanks! That saved me a good deal of troubleshooting. It turned out the problem was a hard path to a file inside the C program which caused it to run correctly when invoked from it's native directory, but caused a segfault when called by Qt since the paths were different. The problem is completely fixed now.


Log in to reply
 

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