Create signal with / from stdin



  • Linux and Qt novice
    Process proc_send runs and starts an app named proc_recv, using the QProcess utility. Both apps use Qt 3. App proc_send writes standard output to proc_recv via this line of code:

    proc_recv->WriteToStdin( "text" )

    (for some reason, the triple tic character (same key as the ~ but not shifted.) sequence left that line invisible.)
    I think that works. But I cannot find anything to put in proc_recv such that its standard input is translated into a SIGNAL. I am trying to avoid the concept of polling within proc_recv to capture the data.
    Where should I look to discover how to do this?


  • Qt Champions 2018

    @BKBK I don't understand your description. proc_recv writes to the stdin of the process it manages, right? So, what exactly do you want to do? It's you who writes to its stdin and you know when you're doing so.



  • @BKBK
    Firstly, I know nothing about Qt3 (which is very old!), or that WriteToStdin.

    Unless someone knows of a better way: you should have a read of https://stackoverflow.com/questions/36861177/how-to-get-qiodevice-like-signals-for-console-input-stdin and whatever it references, and Google qsocketnotifier stdin. https://stackoverflow.com/a/7577042 may be your best answer. The upshot which will hopefully apply to your situation is:

    Use QSocketNotifier to be notified of things being available on stdin



  • Here is how I see this concept working so far.
    Within proc_send, create an object as follows:

    QProcess proc_recv = new QProcess( "name_of_an_executable" )
    proc_recv->Start();  // This starts the application running.
    proc_recv->WriteToStdin( "some text" ) // This sends data to the application that was just started and is now running.
    

    Shift perspective to that new application referred to as proc_recv. That app is to read the standard input, just as if it had been started from the command line. But it has things to do while waiting for the standard input.
    That app, proc_recv, is a Qt process, with SIGNALS and SLOTS. I have been searching for documentation about some Qt utility that monitors for the availability of data on the standard input, without success. Without that ability, I must write code that checks for that input. Usually the app posts a read and is stuck there until there is data and the read completes. That is a problem because the app has things to do.
    I will be looking at the article referenced by JonB. I suspect the solution will be to start a new thread to initiate the read and wait on completion. But as I write this, maybe not. Maybe do all the start up work then post the read, let it wait, and the SIGNALs and SLOTs do all the normally assigned tasks.

    Yes, Qt3 is really old. Most of the developers have moved on, the managers don't want to spend a year updating, and I am a Qt and Linux novice and not well qualified to do that update. My apologies on that aspect.



  • @BKBK
    No need for additional threads/blocks/waits (though you could do it that way if you wished). Read the article. So long as your processes are connected via what Qt regards as sockets, if that's what your Qt 3 stuff does, the principle of QSocketNotifier on stdin (0) should work:

    QSocketNotifier *n1 = new QSocketNotifier(0, QSocketNotifier::Read, this);
    connect(n1, SIGNAL(activated(int)), this, SLOT(readInputChannel()));
    
    QSocketNotifier *n2 = new QSocketNotifier(0, QSocketNotifier::Exception, this);
    connect(n2, SIGNAL(activated(int)), this, SLOT(brokenInputChannel()));
    

    You may have to adjust syntax of above for Qt 3, I don't know.



  • I continued working the problem, discovered a complication, wrote it up, then returned here and found the latest post. Working that. Meanwhile, my discovery:

    I checked the link provided, searched a bit more, and found some example code that was said to check for input. Created a Qt timer that triggers once a second. Created a SLOT for the timer and put the check in there. It always said 0 bytes of data. Hmmm, maybe within Qt there is no standard input. So put this code in that SLOT:

    std::string keyboard;
    std::cout << “\n type now\n” << std::flush;
    std::cin >> keyboard;
    std::cout << “\n input was “ << keyboard << “\n” << std::flush;
    

    The app hangs on the input line. The Quit button does not work. Hmmm.
    Went into the constructor and added some std::cout and std::cin and they worked there. But not from within the SLOT for the Qt timer.
    Any thoughts on this? Maybe a bug fixed in later versions of Qt?


  • Qt Champions 2018

    @BKBK said in Create signal with / from stdin:

    QProcess proc_recv = new QProcess( "name_of_an_executable" )
    proc_recv->Start(); // This starts the application running.
    proc_recv->WriteToStdin( "some text" ) // This sends data to the application that was just started and is now running.

    You should first wait until the other process has really started, either using https://doc.qt.io/Qt-5/qprocess.html#waitForStarted or https://doc.qt.io/Qt-5/qprocess.html#started.
    To read from the process use https://doc.qt.io/Qt-5/qprocess.html#readyReadStandardOutput + https://doc.qt.io/Qt-5/qprocess.html#readAllStandardOutput



  • @jsulm
    Your point about waiting for child start before writing to it may be valid.

    However, unless I am misunderstanding (has happened before!). The OP cannot use QProcess::readyReadStandardOutput() etc. because proc_send is the one which spawns proc_recv, proc_recv is the child process and is the receiver, of data on its stdin. QProcess::readyReadStandardOutput() allows a parent to read from child writing to stdout, OP wants child to be reading its stdin from parent, there is no QProcess in the child.

    This is why I have been referring to QSocketNotifier for use in the child, as the only means of knowing when data is ready via a signal as the OP has requested.

    Let me know if it is I who have mixed things up!


  • Qt Champions 2018

    @JonB He wrote in his first post that both apps use Qt



  • @jsulm
    Yes, that's why I'm suggesting QSocketNotifier Qt call in the child. I'm sorry but I think you are wrong, politely. The child needs to be notified when data arrives on its stdin. It does not have a QProcess. You are thinking of when parent wants to read from child, this is child reading from parent, and signal wanted in child. Please re-read, including the two links I posted from stackoverflow which cover precisely this situation.


Log in to reply
 

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