Unable to verify writing to unbuffered Python stdin with QProcess::write()



  • Hi,

    I am calling Python using a QProcess, and want to update a view in real-time based on its output. In order to do this, including while true loops, it was necessary to invoke using Python's -u flag.

    I have successfully been able to use this to get output from the Python instance. However, whenever I try to write to Python, everything indicates that it has written, but I am unable to verify that this is the case. I have this running in a separate thread, to avoid blocking the GUI.

    This function is responsible for writing to the Python process (p):

    void ExecuteThread::writeToPython(QString text) {
        const char* charPtr = text.toStdString().c_str();
        qint64 noOfBytesWritten = p->write(charPtr, text.length() + 1);
    }

    noOfBytesWritten always returns correctly, yet it will never get to the print statement if I have a Python program like this:

    name = input('What is your name?')
    print(name)

    Am I missing something?



  • AFAIK the python function input(...) blocks until EOL so you have to send a new line (or CR+LF?) - I guess your QString is just a string without a terminating new line? Try so add a p->write('\n');



  • I also thought this, and also tried this line to no avail:
    const char* charPtr = text.toStdString().c_str() + '\n';

    Also the man page for python shows this:

    -u
    Force stdin, stdout and stderr to be totally unbuffered. On systems where it matters, also put stdin, stdout and stderr in binary mode. Note that there is internal buffering in xreadlines(), readlines() and file-object iterators ("for line in sys.stdin") which is not influenced by this option. To work around this, you will want to use "sys.stdin.readline()" inside a "while 1:" loop.

    If stdin is unbuffered, should it even need the newline?



  • @MikePi-Top said:

    I also thought this, and also tried this line to no avail:
    const char* charPtr = text.toStdString().c_str() + '\n';

    Uhm, this shoud not work. here you try to add a newline to a pointer (which points to a null terminated character field) - not append a newline to a string.

    Force stdin, stdout and stderr to be totally unbuffered. On systems where it matters, also put stdin, stdout and stderr in binary mode. Note that there is internal buffering in xreadlines(), readlines() and file-object iterators ("for line in sys.stdin") which is not influenced by this option. To work around this, you will want to use "sys.stdin.readline()" inside a "while 1:" loop.

    If stdin is unbuffered, should it even need the newline?

    All read-methods ending with a line (e.g. readline) expect a terminating new line, as the same says :-) Use read to read the available bytes.



  • Writing a newline separately works, as suggested by micland. Thanks guys!


Log in to reply
 

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