(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. Закройте процесс.

У меня нет никаких проблем с первым и последним шагом — он работает. Проблема в том, что я не могу правильно общаться с шахматным движком (консольное приложение).

Я определенно делаю что-то не так! 😉 Если я раскомментирую process-> closeWriteChannel (); в void Engine :: Write (QByteArray writeBuff), чем я могу написать одну рекомендацию (например, «on», чтобы начать игру) и получить правильный вывод — ответ от шахматного движка (ход). Я не могу отправить следующий комментарий, потому что канал закрыт (это очевидно). Если эта строка закомментирована, я не могу получить никакой информации.

Я хотел бы сделать:

  1. Начать процесс:

    Двигатель двигатель;
    engine.startProcess ();

  2. Общайтесь (отправьте пользователя и получите движение двигателя):

    engine.Write («a2a3»);
    engine.Write («b2b3»);
    engine.Write («c2c3»);

  3. Закройте процесс.

Я сделал все возможное, чтобы найти ответ (помощь, Google). Можете ли вы помочь мне найти решение?

Спасибо!

2

Решение

Я вижу две проблемы с вашим кодом:

  1. ты звонишь writeBuf.clear() в вашем Engine::Write функция-член, не делай этого.
  2. Я предполагаю, что ваша внешняя программа разделяет команды, ища символ новой строки. Пожалуйста, попробуйте что-то вроде engine.Write( "a2a3\n" ),
1

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]