当 QProcess 需要用户使用 Qt 输入时如何读取
How to read when QProcess need user input with Qt
我正在使用 Qt 来实现一个允许为嵌入式系统开发的接口。
我面临一个问题:为了将程序闪存到嵌入式系统中,我使用 QProcess,以便使用命令 "make" 和 "make flash"。使没有任何问题,程序编译成功。
但是当我尝试为 "make flash" 做同样的事情时出现了问题,因为控制台正在等待用户输入,他必须按下嵌入式系统上的按钮。
但是 QProcess returns 标准输出只有在脚本完成时才会输出,所以我没有消息 "press a button"。
所以我的问题是:我如何知道 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 是一个 class 用于在我的界面中显示控制台报告
[编辑] 我尝试了 Vladimir 所说的。不幸的是我没有我的 material 所以我不能测试它但是我已经完成了这个脚本 (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");
}
但它什么都不做
我的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();
}
我正在使用 Qt 来实现一个允许为嵌入式系统开发的接口。
我面临一个问题:为了将程序闪存到嵌入式系统中,我使用 QProcess,以便使用命令 "make" 和 "make flash"。使没有任何问题,程序编译成功。
但是当我尝试为 "make flash" 做同样的事情时出现了问题,因为控制台正在等待用户输入,他必须按下嵌入式系统上的按钮。
但是 QProcess returns 标准输出只有在脚本完成时才会输出,所以我没有消息 "press a button"。
所以我的问题是:我如何知道 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 是一个 class 用于在我的界面中显示控制台报告
[编辑] 我尝试了 Vladimir 所说的。不幸的是我没有我的 material 所以我不能测试它但是我已经完成了这个脚本 (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");
}
但它什么都不做
我的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();
}