在返回之前等待输出的自定义QProcess对象

Custom QProcess object to wait for output before returning

本文关键字:自定义 QProcess 对象 输出 等待 返回      更新时间:2023-10-16

注意:标题并不能准确地传达问题,请根据需要进行编辑

  1. 关于类和描述的信息
  2. 问题
  3. 代码示例等
  4. TL;DR

1.信息:

我已经创建了一个名为m_Proc的自定义QProcess类。

#include "misc_serv"
using namespace misc_serv;
class GEN_SERVSHARED_EXPORT m_Proc : public QProcess
{
Q_OBJECT
public:
int exitCode = -1;
QString _out;
s_i_combo si;
QList<s_i_combo> sch_in_List;
m_Proc(QList<s_i_combo> i_s_list, QObject *parent = 0);
m_Proc(s_i_combo i_s_obj, QObject *parent);
m_Proc(QObject *parent);
void setProcessBlocks(s_i_combo _si);
void setProcessBlocks(QList<s_i_combo> _si_list);
~m_Proc() {}
private:
s_i_combo getSearchInput();
void initConnectors();
public slots:
void myReadyReadStandardOutput();
void myFinished(int i);
signals:
void finishedSignal();
};

此类的目的是使用QProcess父级发出的信号,这将允许我从read*()write()QProcess

当达到最终输出时,QProcess::finished(int)连接到分配QProcess的最终输出和退出代码的方法

然后从m_Proc发出一个信号,该信号将通知父类。该信号被命名为(非常有创意的)finishedSignal

CCD_ 9由另一个名为CCD_。

#include "m_proc.h"
class GEN_SERVSHARED_EXPORT gen_serv : public QObject
{
Q_OBJECT
private:
QObject *parent;
QProcess *p;
int MSEC = 1000;
m_Proc *m;
int exitCode = -1;
QString _proc_out;
void init_connector();
private slots:
void getResults();
public:
gen_serv(QObject *_parent = new QObject());
virtual ~gen_serv();
void runCommand(const QString _prog);
void runCommand(const QString _prog, const QStringList args);
void runCommand(const QString _prog, const QString _sSearch, const QString _sInput);
void runCommand(const QString _prog, const QStringList args, const QString _sSearch, const QString _sInput);
void runCommand(const QString _prog, s_i_combo siCombo);
void runCommand(const QString _prog, const QStringList args, s_i_combo siCombo);
void runCommand(const QString _prog, QList<s_i_combo> siList);
void runCommand(const QString _prog, const QStringList args, QList<s_i_combo> siList);
QString getRunCommand_Output();
int getRunCommand_ExitCode();
QProcess* createProcess(QString cmd/*, int t_sec = 30*/);
};

gen_serv为m_Proc提供了各种"构造函数方法"。这些构造函数方法调用runCommand。这些构造函数及其参数允许各种处理能力,从基本程序执行到详细的I/O过程。

2.问题:

在qt控制台应用程序中,我创建了一个gen_serv对象,并使用它来"运行命令",例如:

//main.cpp
gen_serv *gen_proc
gen_proc = new gen_serv();
gen_proc->runCommand("sh", QStringList()
<< "-c"
<< "echo sleeping; sleep 2; echo hello...");
qDebug() << gen_proc->_proc_out;

根据我的m_Proc的工作方式,应该返回:"你好…">

上面要运行的命令与(据我所知)相同

$ sh -c "echo sleeping; sleep 2; echo hello..."
sleeping
hello...

但是:它返回一个空的QString,并且:

qDebug() << QString::number(gen_proc->exitCode);

输出:"-1">

3.额外的代码示例等-这让我相信:

问题不在于m_Proc,而在于我的父类gen_serv

目前,在调用void gen_serv::runCommand()之后,我运行QObject::connect(),如下所示(getResults()只获取_proc_outexitCode,并将它们分配给gen_serv用于访问器方法):

QObject::connect(m, SIGNAL(finishedSignal()), this, SLOT(getResults()));

然而,这被执行,并且runCommand()返回到main.cpp,其中qDebug()立即调用gen_proc->_proc_out并且qDebug()将输出:

_gen_proc->_proc_out = ""
_gen_proc->exitcode = -1

4.TL;DR

我需要什么:

我需要设计一个方法,它将在/或替换连接(在gen_serv中)之后运行。

此方法将等待信号发出,因此调用QProcess.start()runCommand()将不会返回,直到m_ProcfinishedSignal发出,从而保证有效的输出/退出代码值。

有什么建议吗?

我找到了一个解决方案,我无法判断它是否是一个好的解决方案,但它是有效的。

可能的解决方案:(使用QProcess::wait*()的)

在我调用QObject::connect()的方法(gen_serv::init_connector())中,我更改/添加了一些额外的行。

void gen_serv::init_connector(){
if (m->waitForStarted()) {
QObject::connect(m, SIGNAL(finishedSignal()), this, SLOT(getResults()));
if (!m->waitForFinished())
qDebug() << "program is hanging, check m_Proc description for possible hang issues...: n" << m->errorString();
}
else{
if (m->errorString().contains("No such file or directory"))
qDebug() << "check program and arguments - something seems wrong. Cannot find something... : n" << m->errorString();
else
qDebug() << m->errorString();
}
}

解决方案非常直接,但尽管如此,我还是会提供一个简短的描述:

  • 首先,检查进程是否真的已经启动。如果没有,则显示一条包含错误字符串的适当消息

注意:我注意到一个错误字符串,如:

"execp:没有这样的文件或目录通常意味着program没有找到

即路径不正确或有多余的参数或应用程序不接受任何参数

  • 如果QProcess已启动,则connect()signalslot。其次是CCD_ 38

waitForFinished()的原因是此方法等待QProcess::finished(int)信号。

这允许应用程序等待处理完成(这正是我所需要的)。

希望这能帮助