QProcess & Child Process and Input/Output



  • This question is related input and output between parent process and child process on Windows Platform. I have created child process from parent process using the QProcess. ChildProcess simply prints the output continuously. My intent is that parent process should print whatever child process output. Code snippet for what I have done is given below. I felt following code should work. I'm observing two issues.

    1. I don't see prints written by child process are coming to parent process.
    2. I don't see slot is getting executed.

    I'm sure 2nd issue is related to first one itself.

    Any opinion on this piece of code would help.

    1. Parent Program
      @int main(int argc, char *argv[])
      {
      QApplication a(argc, argv);
      MyWidget w;
      QProcess mychild;
      mychild.start("mychild");
      QObject::connect(&mychild,SIGNAL(readyRead()),&w,SLOT(datahascome()));

      while(1) {
      qDebug() << " MyOutput-1 =" << mychild.readAll().data();
      qDebug() << " MyOutput-2 =" << mychild.readAllStandardOutput().data();
      QThread::currentThread()->sleep(1);
      char *buf = new char[100];
      mychild.read(buf,100);
      qDebug() << buf;
      qDebug() << " Data =" << mychild.read(100).data();
      }
      return a.exec();
      }

    Child Program

    int main(int argc, char *argv[])
    {
    QCoreApplication a(argc, argv);
    int count=0;
    while(1) {
    qDebug() << "Child Process output"<<endl;
    cout << "Child Process Output \n" <<endl;
    QThread::currentThread()->sleep(1);
    }
    return a.exec();
    }
    @


  • Moderators

    Maybe the start() failed for whatever reason? Normally you would connect to the started() and error() signals but since you run it out of event loop you should call mychild.waitForStarted() before and check if it returns true.

    As for the slot, it's a much too common misconception that something like this will work as expected:
    @
    int main(int argc, char *argv[])
    {
    QCoreApplication a(argc, argv);
    //do anything Qt'ish like connect, threads etc.
    ...
    //at this point you're done
    a.exec(); //this basically does an infinite empty loop at this point.
    }
    @
    You need to run your code inside the exec() event loop. not before it even starts.



  • Thank you for your reply. Start did not fail. It really started the child process. In the above code, I can read all the outputs from child only if child exits. Honestly I did not understand your explanation on "Slot and misconception".

    Now, since it single threaded parent process, I did not worry about starting an event loop before reading chilld output. May be I can starting a event loop before reading from childoutput in parent process.


  • Moderators

    QProcess can be used outside an event loop. That was not my point. If you're able to read the output after the child exits then it sounds like it's not flushing its buffer (until the program is ending and the flush is implicit). On the other hand you're using endl so it should flush. Just for the sake of test could you add cout.flush() after writing?

    As for the signal/slots in event loop. I just meant that many times i see this construct (often with networking) that people create connections and do some waiting or signal/slot dependent blocking operations and only after they're done they call exec() and wonder why their slots don't get called.

    It's the same with your code. You're making a connection to the readyRead signal, which will be delivered only once you enter exec(). But since you have an endless loop before that it never will.
    What I meant by running your code inside an event loop is something I described in few other topics, for example "here":http://qt-project.org/forums/viewthread/36793/#156769



  • Thank you. This gave me a good hint. I already used flush. It did not work.
    Regarding the slot, I was just thinking that it is single threaded application as I did not start the separate thread. If single threaded application, I can make sig/slot working. This is where I failed to notice. After your post I realized that data is coming from the other process and internally it has to work with event loop for the sig/slot to work.

    Now I started event loop and then started sending/receiving the data. Now data is received and sig/slot is also called.

    One question still remained is that why was it not displaying the data even though flush/endl exist. It only displayed all the data when the child exits and this scenario worked without evenloop as well.


Log in to reply
 

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