7

父进程将字符串写入"Message\n"子进程标准输入。但是子进程没有收到它。代码中的问题在哪里?

Qt 4.7.3

父进程代码:

// 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";
}

子进程代码:

// 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
}
4

3 回答 3

7

没有办法在 Qt 事件循环中为 stdin/stdout 事件进行可移植的连接。以下适用于非 Windows 平台:

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”是文件描述符(stdin)。

我将使用上述方法,然后通过从标准输入读取并生成信号的阻塞线程在 Windows 上模拟类似的东西:

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));
         }
     }
};

然后,在子进程中:

StdinThread *t = new StdinThread(this);
connect(t, SIGNAL(incomingData(QByteArray)), this, SLOT(processInputData(QByteArray)));
connect(t, SIGNAL(finished()), this, SLOT(brokenInputChannel()));
t->run();
于 2011-09-28T00:21:01.480 回答
1

文档说它QFile永远不会发出信号readyRead()

但是有一个私有类:QWinEventNotifierin src/corelib/kernel/qwineventnotifier_p.h(link)可能与GetStdHandle(STD_INPUT_HANDLE).

另一种选择是在专用线程内使用阻塞循环等待输入:

QTextStream cin(stdin, QIODevice::ReadOnly);
while(!cin.atEnd())
{
   QString line = cin.readLine();
   emit newLine(line);
}

您还可以查看其他 RPC 方法(例如QLocalSocket, QSharedMemory)。

于 2011-09-18T16:48:50.493 回答
0

我相信你需要做的是从实际的 QProcess 对象中读取(如果我理解正确的话,在这种情况下是 childProcess)。

注意 QProcess 实际上是 QIODevice 的子类,还要特别注意以下函数:

QProcess::setReadChannel()
QProcess::readAllStandardOutput()

您应该能够使用 QProcess 对象的 readyRead() 信号,而不是创建 QFile 来尝试读取标准输入。这不起作用的原因是您的 QFile 与 MainWindow 的同一进程相关联,而不是您的子进程。

于 2011-09-17T22:51:59.210 回答