(Qt - QProcess)与控制台应用程序通信

时间:2013-02-13 13:11:15

标签: c++ qt qprocess

我试图将Qt控制台应用程序与另一个用C编写的控制台应用程序(国际象棋引擎 - TSCP)进行通信。

我创建了这个类:

#include "engine.h"

Engine::Engine(QObject *parent) :
    QProcess(parent)
{
}

Engine::~Engine()
{
    delete process;
}

void Engine::startProcess()
{
    process = new QProcess( this );

    process->setReadChannel( QProcess::StandardOutput );

    connect( process, SIGNAL(error(QProcess::ProcessError)), this, SLOT(error(QProcess::ProcessError)) );
    connect( process, SIGNAL(finished(int,QProcess::ExitStatus)), this, SLOT(finished(int,QProcess::ExitStatus)) );
    connect( process, SIGNAL(readyReadStandardError()), this, SLOT(readyReadStandardError()) );
    connect( process, SIGNAL(readyReadStandardOutput()), this, SLOT(readyReadStandardOutput()) );
    connect( process, SIGNAL(started()), this, SLOT(started()) );
    connect( process, SIGNAL(stateChanged(QProcess::ProcessState)), this, SLOT(stateChanged(QProcess::ProcessState)) );

    //process->start( "/usr/bin/konsole --nofork -e ./TSCP" );
    process->start( "./TSCP" );
    process->waitForStarted(-1);
}

void Engine::stopProcess()
{
    //process->write( "bye" );
    process->closeWriteChannel();
}

void Engine::Write( QByteArray writeBuff )
{
    writeBuff.clear();
    qDebug() << "Sending command: " + writeBuff;
    process->write( writeBuff );
    //process->closeWriteChannel();
}

QByteArray Engine::Read()
{
    readBuffer = process->readAllStandardOutput();
    return readBuffer;
}

void Engine::error( QProcess::ProcessError error )
{
    qDebug() << "Error!";
    qDebug() << error;
}

void Engine::finished( int exitCode, QProcess::ExitStatus exitStatus )
{
    qDebug() << "The process has finished.";
    qDebug( "Exit code: %i", exitCode );
    qDebug( "Exit status: %i", exitStatus );
}

void Engine::readyReadStandardError()
{
    qDebug() << "Ready to read error.";
    qDebug() << process->readAllStandardError();
}

void Engine::readyReadStandardOutput()
{
    qDebug() << "The output:";
    readBuffer = process->readAllStandardOutput();
    qDebug() << readBuffer;
    //process->closeReadChannel( QProcess::StandardOutput );
    //process->waitForBytesWritten();
}

void Engine::started()
{
    qDebug() << "The process has started.";
}

void Engine::stateChanged( QProcess::ProcessState newState )
{
    switch( newState )
    {
    case 0:
        qDebug() << "The process is not running.";
        break;
    case 1:
        qDebug() << "The process is starting, but the program has not yet been invoked.";
        break;
    case 2:
        qDebug() << "The process is running and is ready for reading and writing.";
        break;
    }
}

我的main.cpp看起来就像那样:

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);

    qDebug() << "----------------------------------";

    Engine engine;
    engine.startProcess();
    engine.Write( "on" );
    qDebug() << "----------------------------------";

    return a.exec();
}

我正在努力实现:

  1. 启动流程 - 国际象棋引擎。
  2. 向流程发送命令 - 引擎。
  3. 收到答案(能够显示,处理)。
  4. 继续沟通(步骤2,3)。
  5. 关闭此过程。
  6. 我对第一步也是最后一步没有任何困难 - 它正在发挥作用。问题是我无法与国际象棋引擎(控制台应用程序)正常通信。

    我肯定做错了什么! ;)如果我取消注释process-&gt; closeWriteChannel();在void Engine :: Write(QByteArray writeBuff)函数中,我可以写一个推荐(例如'on'开始游戏)并从国际象棋引擎接收正确的输出 - 响应(移动)。我不能发送下一个表扬,因为频道已关闭(很明显)。如果此行被注释,我将无法收到任何信息。

    我想这样做:

    1. 启动流程:

      发动机引擎;  engine.startProcess();

    2. 通讯(发送用户并接收引擎移动):

      engine.Write(“a2a3”); engine.Write(“b2b3”); engine.Write(“c2c3”);

    3. 关闭此过程。

    4. 我尽力找到答案(帮助,谷歌)。你能帮我找到解决方案吗?

      谢谢!

1 个答案:

答案 0 :(得分:1)

我发现您的代码有两个问题:

  1. 您在writeBuf.clear()会员功能中致电Engine::Write,请勿这样做。
  2. 我猜您的外部程序通过查找换行符来分隔命令。请尝试engine.Write( "a2a3\n" )
  3. 之类的内容