[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&#40;&#41;;
    

    }@

    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... :(


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.