Как читать, когда QProcess нужен пользовательский ввод с Qt - PullRequest
0 голосов
/ 01 февраля 2020

Я использую Qt для реализации интерфейса, позволяющего разрабатывать для встраиваемой системы.

Я столкнулся с проблемой: для того, чтобы запустить sh программу во встроенную систему, я использую QProcess, чтобы использовать команды «make» и «make fla sh». Чтобы сделать это не проблема, и программа успешно компилируется.

Но когда я пытаюсь сделать то же самое для "make fla sh", возникает проблема, потому что консоль ожидает ввода данных пользователем, он должен нажать кнопку во встроенной системе.

Но QProcess возвращает стандартный вывод только после завершения скрипта, поэтому у меня нет сообщения «нажать кнопку».

Итак, мой вопрос: как я могу узнать, когда QProcess требуется ввод данных пользователем? Или, если это невозможно, как я могу динамически открыть консоль с помощью Qt и запустить команду?

Я попытался сказать то, что здесь сказано: https://www.qtcentre.org/threads/47538-QProcess-read-from-stdout-lively

А вот мой код:

compilator->start("make flash");    
compilator->waitForFinished();
QByteArray errors = compilator->readAllStandardError();
QString stringError(errors);
QByteArray message = compilator->readAll();
QString stringMessage(message);
m_logForm->setText("Project path : "
                   + pathProject + "\n"
                   + "Flash finished with exit code " + QString::number(compilator->exitCode()) + "\n"
                   + stringError + "\n"
                   + stringMessage + "\n");

Где m_logFrom - используемый класс чтобы отобразить консольный отчет в моем интерфейсе

[EDIT] Я попробовал то, что сказал Владимир. К сожалению, у меня нет своего материала, поэтому я не могу его протестировать, но я сделал этот скрипт (test.bat), чтобы протестировать:

set /p answer=Do you want to create it now (Y/N)?

Вот мой новый код:

QProcess *compilator = new QProcess(this);
    connect(compilator, &QProcess::readyReadStandardOutput, [compilator, this](){
        QString output =compilator->readAll();
        qDebug() << "output: "<< output;
        m_logForm->setText("Flash finished with exit code " + QString::number(compilator->exitCode()) + "\n"
                           + output + "\n");
    });

    connect(compilator, &QProcess::readyReadStandardError, [compilator, this](){
        QString err = compilator->readAllStandardError();
        qDebug() << "error: "<<err;
        m_logForm->setText("Flash finished with exit code " + QString::number(compilator->exitCode()) + "\n"
                           + err + "\n");
    });
    m_logForm->setText("Flashing to serial port "+m_Serial + "\n");
    compilator->setWorkingDirectory(pathProject);

    compilator->start("test.bat");


    }

Но это ничего не делает

1 Ответ

1 голос
/ 03 февраля 2020

My test.bat

set /p answer=Do you want to create it now (Y/N)?
echo "user response:" %answer%
pause

Код запускает пакетную команду, читает ее вывод и записывает ответ в процесс:

QProcess *compilator = new QProcess(this);

connect(compilator, &QProcess::readyReadStandardOutput, [compilator, this]() 
{
    QString output = compilator->readAllStandardOutput().simplified();
    qDebug().noquote() << "output: " << output;

    if (output.contains("(Y/N)?", Qt::CaseInsensitive))
    {
        compilator->write("Y\n"); // write our answer to the process
    }
    else if (output.contains(". . .", Qt::CaseInsensitive))
    {
        compilator->write("\n"); // simulate press any key to process
    }
});

connect(compilator, &QProcess::readyReadStandardError, [compilator, this]() 
{
    QString err = compilator->readAllStandardError().simplified();
    qWarning().noquote() << "error: " << err;
});

// Handle the finished() signal:
connect(compilator, QOverload<int, QProcess::ExitStatus>::of(&QProcess::finished),
    [compilator, this](int exitCode, QProcess::ExitStatus exitStatus) 
{ 
    qDebug() << "compilator process finished with exit code =" << exitCode
        << "and exit status =" << exitStatus;
});    

compilator->start("test.bat");

if (compilator->waitForStarted()) // use to check start errors
{
    qDebug() << "compilator process started ok";
}
else
{
    qCritical() << "compilator process start FAILED:" << compilator->errorString();
}
...