Я пытаюсь связать консольное приложение 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();
}
Я пытаюсь добиться:
У меня нет никаких проблем с первым и последним шагом — он работает. Проблема в том, что я не могу правильно общаться с шахматным движком (консольное приложение).
Я определенно делаю что-то не так! 😉 Если я раскомментирую process-> closeWriteChannel (); в void Engine :: Write (QByteArray writeBuff), чем я могу написать одну рекомендацию (например, «on», чтобы начать игру) и получить правильный вывод — ответ от шахматного движка (ход). Я не могу отправить следующий комментарий, потому что канал закрыт (это очевидно). Если эта строка закомментирована, я не могу получить никакой информации.
Я хотел бы сделать:
Начать процесс:
Двигатель двигатель;
engine.startProcess ();
Общайтесь (отправьте пользователя и получите движение двигателя):
engine.Write («a2a3»);
engine.Write («b2b3»);
engine.Write («c2c3»);
Закройте процесс.
Я сделал все возможное, чтобы найти ответ (помощь, Google). Можете ли вы помочь мне найти решение?
Спасибо!
Я вижу две проблемы с вашим кодом:
writeBuf.clear()
в вашем Engine::Write
функция-член, не делай этого.engine.Write( "a2a3\n" )
,Других решений пока нет …