Parent process write string "Message\n"
to child process stdin. But child process don't receive it. Where is the problem in the code?
Qt 4.7.3
Parent process code:
// class TestParent : public QMainWindow
void TestParent::createChildProcess()
{
childProcess = new QProcess( this );
connect( childProcess, SIGNAL( started() ),
this, SLOT( childProcessStarted() ) );
connect( childProcess, SIGNAL( bytesWritten( qint64 ) ),
this, SLOT( bytesWritten( qint64 ) ) );
childProcess->start( "TestChild.exe", QProcess::ReadWrite );
}
void TestParent::writeToChildProcessOutput()
{
qint64 bytesWritten = childProcess->write( "Message\n" );
qDebug() << "ret: " << bytesWritten << " bytes written";
}
void TestParent::bytesWritten()
{
qDebug() << "slot: " << bytesWritten << " bytes written";
}
Child process code:
// class TestChild : public QMainWindow
void TestChild::TestChild()
// QFile TestChild::input;
connect( &input, SIGNAL( readyRead() ),
this, SLOT( readInput() ) );
input.open( 0, QIODevice::ReadOnly ); // stdin
}
void TestChild::readInput()
{
QString line;
line.append( '(' );
line.append( QString::number( input.bytesAvailable() ) )
line.append( ')' );
line.append( input.readAll() );
list.append( line ); // add line to QListView
}
There is no way to portably hookup in the Qt event loop for stdin/stdout events. The following works on non-Windows platforms:
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()));
"0" is the file descriptor (stdin).
I would use the above and then simulate something similar on Windows through a blocking thread that reads from stdin and generates a signal:
class StdinThread : public QThread
{
Q_OBJECT
signals:
void incomingData(QByteArray data);
public:
void run(void)
{
char buf[1024];
while (1)
{
int sz = fread(buf, 1, 1024, stdin);
if (sz == 0)
return;
emit incomingData(QByteArray(buf, sz));
}
}
};
then, in the child process:
StdinThread *t = new StdinThread(this);
connect(t, SIGNAL(incomingData(QByteArray)), this, SLOT(processInputData(QByteArray)));
connect(t, SIGNAL(finished()), this, SLOT(brokenInputChannel()));
t->run();
The documentation says that QFile
doesn't ever emit the signal readyRead()
.
But there is a private class: QWinEventNotifier
in src/corelib/kernel/qwineventnotifier_p.h
(link) that might work with GetStdHandle(STD_INPUT_HANDLE)
.
Another alternative is to wait for input with a blocking loop inside a dedicated thread:
QTextStream cin(stdin, QIODevice::ReadOnly);
while(!cin.atEnd())
{
QString line = cin.readLine();
emit newLine(line);
}
You could also look at other RPC methods (e.g. QLocalSocket
, QSharedMemory
).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With