gpt4 book ai didi

c++ - 在 Qt 控制台应用程序中读写 QProcess

转载 作者:行者123 更新时间:2023-11-30 03:34:44 25 4
gpt4 key购买 nike

注意:这似乎是一个特定的问题,但希望它可以针对所有相关问题进行编辑

我需要与 QProcess 对象交互。

问题:

我没有从 QProcess 得到任何输出打电话后 QProcess:write(input)

更多信息:

遍历 doc pages引导我在下面创建一个示例:

我有一个脚本请求用户输入,并最终根据用户输入显示适当的消息。

测试:

在我的测试脚本中添加“日志”功能后,发生了以下情况:

  • 脚本执行
  • 脚本请求用户输入(由“第一个”qDebug() << p->readAll() 确认)
  • 脚本接受来自 QProcess 的输入(由脚本“日志输出”确认)

在此之后,没有收到任何输出。以下 2 个调试语句都触发(即每个等待 30 秒)

if (!p->waitForReadyRead()) {
qDebug() << "waitForReadyRead() [false] : CODE: " << QVariant(p->error()).toString() << " | ERROR STRING: " << p->errorString();
}
if (!p->waitForFinished()) {
qDebug() << "waitForFinished() [false] : CODE: " << QVariant(p->error()).toString() << " | ERROR STRING: " << p->errorString();
}

其次是:

QString s = QString(p->readAll() + p->readAllStandardOutput());

哪里s是一个空字符串。

问题是 s 应该包含“成功”或“失败”

调用代码:

QString cmd = QString("sh -c \"/path/to/bashscript.sh\"");
QString input = QString("Name");
QString result = runCommand(cmd, input)

处理代码:

//takes 2 parameters, 
// cmd which is the code to be executed by the shell
// input which acts as the user input

QString runCommand(QString cmd, QString input){
QProcess *p = new QProcess(new QObject());
p->setProcessChannelMode(QProcess::MergedChannels); //no actual reason to do this
p->start(cmd);
if (p->waitForStarted()) {
if (!p->waitForReadyRead()) {
qDebug() << "waitForReadyRead() [false] : CODE: " << QVariant(p->error()).toString() << " | ERROR STRING: " << p->errorString();
}
if (!p->waitForFinished()) {

//reads current stdout, this will show the input request from the bash script
//e.g. please enter your name:
qDebug() << p->readAll();

//here I write the input (the name) to the process, which is received by the script
p->write(ps.toLatin1());

//the script should then display a message i.e. ("success" o "failed")
if (!p->waitForReadyRead()) {
qDebug() << "waitForReadyRead() [false] : CODE: " << QVariant(p->error()).toString() << " | ERROR STRING: " << p->errorString();
}
if (!p->waitForFinished()) {
qDebug() << "waitForFinished() [false] : CODE: " << QVariant(p->error()).toString() << " | ERROR STRING: " << p->errorString();
}
}
QString s = QString(p->readAll() + p->readAllStandardOutput());
return s;
}
else{
qDebug() << "waitForStarted() [false] : CODE: " << QVariant(p->error()).toString() << " | ERROR STRING: " << p->errorString();
}
p->waitForFinished();
p->kill();
return QString();
}

script.sh ( -rwxrwxr-x )

#!/bin/bash
#returns
# "success" on non empty $n value
# "failed: on empty $n value
#
echo "enter your name:"
read n
if [[ ! -z $n ]];
then
echo "success"
exit 0;
else
echo "failed"
exit 1;
fi

更新

@KevinKrammer 我按照你说的修改了运行命令,还使用带有 args 的 QStringList。

仍然没有得到输出,实际上是 waitForReadyRead()waitForFinished() returns false立即。

调用方式:

QString r = runCommand(QString("text"));

处理代码:

QString runCommand(QString input){      

QProcess *p = new QProcess(new QObject());
p->setProcessChannelMode(QProcess::MergedChannels);

//script is the same script refered to earlier, and the `cd /home/dev` IS required
p->start("sh", QStringList() << "-c" << "cd /home/dev" << "./script");
;
if (p->waitForStarted()) {
if (!p->waitForReadyRead(5000)) {
qDebug() << "waitForReadyRead() [false] : CODE: " << QVariant(p->error()).toString() << " | ERROR STRING: " << p->errorString();
}
qDebug() << p->readAll();
p->write(input.toLatin1());
if(!p->waitForFinished(5000)){
qDebug() << "waitForFinished() [false] : CODE: " << QVariant(p->error()).toString() << " | ERROR STRING: " << p->errorString();
}
QString s = QString(p->readAll() + p->readAllStandardOutput());
return s;
}
else{
qDebug() << "waitForStarted() [false] : CODE: " << QVariant(p->error()).toString() << " | ERROR STRING: " << p->errorString();
}
p->waitForFinished();
p->kill();
return QString();
}

进程的终端输出:

started
readChannelFinished
exit code = "0"
waitForReadyRead() [false] : CODE: "5" | ERROR STRING: "Unknown error"
""
waitForFinished() [false] : CODE: "5" | ERROR STRING: "Unknown error"
Press <RETURN> to close this window...

对此有何想法?

更新 2

@Tarod 感谢您花时间提出解决方案。

它有效,但并不完全符合预期。

我完全复制了你的代码。

mReadyReadStandardOutput() 中做了一些改动

请参阅下面的其他信息。

问题:

运行应用程序(和脚本)后,我得到一个结果 -> 好极了

每次都是错误的结果,即“失败”。 -> 不太好

终端输出:

void MyProcess::myReadyRead()
void MyProcess::myReadyReadStandardOutput()
"enter your name:\n"
""
void MyProcess::myReadyRead()
void MyProcess::myReadyReadStandardOutput()
"failed\n"
Press <RETURN> to close this window...

脚本内容:

#!/bin/bash
echo "enter your name:"
read n
echo $n > "/tmp/log_test.txt"
if [[ ! -z "$n" ]];
then
echo "success"
exit 0;
else
echo "failed"
exit 1;
fi

/tmp/log_test.txt输出

myname

从控制台手动运行:

dev@dev-W55xEU:~$ ls -la script 
-rwxrwxr-x 1 dev dev 155 Jan 25 14:53 script*

dev@dev-W55xEU:~$ ./script
enter your name:
TEST_NAME
success

dev@dev-W55xEU:~$ cat /tmp/log_test.txt
TEST_NAME

完整代码:

#include <QCoreApplication>
#include <QProcess>
#include <QDebug>

class MyProcess : public QProcess
{
Q_OBJECT

public:
MyProcess(QObject *parent = 0);
~MyProcess() {}

public slots:
void myReadyRead();
void myReadyReadStandardOutput();
};

MyProcess::MyProcess(QObject *parent)
{
connect(this,SIGNAL(readyRead()),
this,SLOT(myReadyRead()));
connect(this,SIGNAL(readyReadStandardOutput()),
this,SLOT(myReadyReadStandardOutput()));
}

void MyProcess::myReadyRead() {
qDebug() << Q_FUNC_INFO;
}

void MyProcess::myReadyReadStandardOutput() {
qDebug() << Q_FUNC_INFO;
// Note we need to add \n (it's like pressing enter key)
QString s = this->readAllStandardOutput();
qDebug() << s;
if (s.contains("enter your name")) {
this->write(QString("myname" + QString("\n")).toLatin1());
qDebug() << this->readAllStandardOutput();
}
}

int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);

MyProcess *myProcess = new MyProcess();

QString program = "/home/dev/script";

myProcess->start("/bin/sh", QStringList() << program);

a.exec();
}

#include "main.moc"

脚本问题? Q流程问题?

最佳答案

不幸的是我没有你所有的代码,所以我做了一个例子。希望对您有所帮助。

如果我将我的代码与您的代码进行比较,我认为问题可能是您在编写后没有调用 readAllStandardOutput() 或者您可能没有在调用 exec()你的 main.cpp。

#include <QCoreApplication>
#include <QProcess>
#include <QDebug>

class MyProcess : public QProcess
{
Q_OBJECT

public:
MyProcess(QObject *parent = 0);
~MyProcess() {}

public slots:
void myReadyRead();
void myReadyReadStandardOutput();
};

MyProcess::MyProcess(QObject *parent)
{
connect(this,SIGNAL(readyRead()),
this,SLOT(myReadyRead()));
connect(this,SIGNAL(readyReadStandardOutput()),
this,SLOT(myReadyReadStandardOutput()));
}

void MyProcess::myReadyRead() {
qDebug() << Q_FUNC_INFO;
}

void MyProcess::myReadyReadStandardOutput() {
qDebug() << Q_FUNC_INFO;
// Note we need to add \n (it's like pressing enter key)
this->write(QString("myname" + QString("\n")).toLatin1());
// Next line no required
// qDebug() << this->readAll();
qDebug() << this->readAllStandardOutput();

}

int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);

MyProcess *myProcess = new MyProcess();

QString program = "/home/fran/code/myscript.sh";

myProcess->start("/bin/sh", QStringList() << program);

a.exec();
}

#include "main.moc"

测试应用程序的脚本:

echo "enter your name:"
read n
if [ ! -z "$n" ];
then
echo "success"
exit 0;
else
echo "failed"
exit 1;
fi

关于c++ - 在 Qt 控制台应用程序中读写 QProcess,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41848939/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com