[Qt - QProcess] Communication with a console application
-
I'm trying to communicate Qt console application with another console application written in C (chess engine - TSCP).
I created this class:
@#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;
}
}@My main.cpp looks just like that:
@int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);qDebug() << "----------------------------------"; Engine engine; engine.startProcess(); engine.Write( "on" ); qDebug() << "----------------------------------"; return a.exec();
}@
I am trying to achieve:
Start the process - chess engine.
Send a command to the process - engine.
Receive an answer (be able to display, process it).
Continue the communication (steps 2, 3).
Close the process.
I don't have any difficulties with the first and last step - it's working. The problem is that i can't communicate properly with the chess engine (console application).
I am definitely doing something wrong! ;) If I uncomment process->closeWriteChannel(); in void Engine::Write( QByteArray writeBuff ) function than I can write one commend (for exampe 'on' to start the game) and receive the correct output - response from the chess engine (move). I cannot send the next commend, because the channel is closed (it is obvious). If this line is commented I cannot receive any information.
I would like to do:
Start the process:
Engine engine;
engine.startProcess();Comunicate (send the user and receive the engine move):
engine.Write( "a2a3" );
engine.Write( "b2b3" );
engine.Write( "c2c3" );Close the process.
I did my best to find the answer (help, google). Can you help me to find the solution?
Thank you!
-
Maybe a little offtropic but: If you want to write a chess UI in Qt, maybe we can got together because I started to do that also :). Fut 1.) Don't have so much time to do that alone and 2.) It's a lot of work, so that the project is atm frozen... :(