0

I'm trying to get a Qt application to communicate with a python program. The most logical solution seemed to be to run a QProcess in the Qt app containing the Python code. I want to send commands using std input and if applicable read via the std output.

However, even this simple example doesn't seem to work. These two python snippets:

import os
import time

while True:
    print "test"
    time.sleep(2)

Together with the simple Qt code:

MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
{
    process = new QProcess(this);
    process->start("/home/user/test.py");

    connect(process, SIGNAL(stateChanged(QProcess::ProcessState)), SLOT(printProcessStatus()));
    connect(process, SIGNAL(error(QProcess::ProcessError)), SLOT(printProcessError()));
    connect(process, SIGNAL(readyRead()), SLOT(printProcessOutput()));
}

void MainWindow::printProcessStatus()
{
    qDebug() << process->state();
}

void MainWindow::printProcessError()
{
    qDebug() << process->errorString();
}

void MainWindow::printProcessOutput()
{
    qDebug() << process->readAll();
}

Doesn't print anything. It does say that the process is "QProcess::ProcessState(Running)", but I can't seem to get the printed output from python into Qt. Similarly I've tried to use the QProcess::write() function to write to a python process but that doesn't work either.

Is this not the intended way to work with QProcess? Is there a better way to do communication between a Qt app and a (child) python program?

  • That was the name of the variable in my code. I changed some explicit names to something more generic for illustration. – Jelco Adamczyk May 09 '17 at 02:23
  • Try putting the `connect` statements *before* the call to `start` -- you're possibly missing some of the signals. – G.M. May 09 '17 at 06:20
  • It does add the 'Starting' state, but it still doesn't provide the expected output of 'test' every 2 seconds. – Jelco Adamczyk May 09 '17 at 13:30
  • Is the python code shown the complete script? I don't see any `#!/usr/bin/python` or similar at the top. What happens if you execute `test.py` at a command line? – G.M. May 09 '17 at 13:36
  • the shebang I'm using is #!/usr/bin/env python2 (as adviced here http://stackoverflow.com/questions/6908143/should-i-put-shebang-in-python-scripts-and-what-form-should-it-take). I have given the file execute permission (chmod +x) and it does print the expected output when executed in the terminal. – Jelco Adamczyk May 09 '17 at 15:11

1 Answers1

1

The problem appears to be the way in which python buffers stdout (it's not line buffered). The code you posted works for me if I change the script to...

#!/usr/bin/env python2
import os
import sys
import time

while True:
    print "test"
    sys.stdout.flush()
    time.sleep(2)

There's probably a better way to achieve the same thing without having to explicitly flush the stream constantly.

Alternatively, if you are on Linux, you could use stdbuf to control the output buffering of the script. Change the process start command to...

process->start("stdbuf", QStringList() << "--output=L" << "/home/user/test.py");
G.M.
  • 12,232
  • 2
  • 15
  • 18