c++ - 自定义 QProcess 对象在返回前等待输出

标签 c++ qt signals-slots qprocess

注意:标题没有准确表达问题,如有必要请随意编辑

  1. 关于类(class)和描述的信息
  2. 问题
  3. 代码示例等
  4. 长话短说

<强>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

m_Proc由另一个名为 gen_serv 的父类处理.

#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对象,并将其用于“runCommands”,例如:

//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 的工作方式,它应该返回:“hello...”

上面要运行的命令与(据我理解)相同:

$ 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。长话短说

我需要什么:

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

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

有什么建议吗?

最佳答案

我找到了一个解决方案,我不知道它是否好,但它有效。

可能的解决方案:(使用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: No such file or directory usually implies that either the program is not found

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

  • 如果 QProcess 启动,则 connect() signalslot。紧随其后的是 waitForFinished()

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

这允许应用程序等到进程完成(这是我的要求)。

希望这对某人有帮助

关于c++ - 自定义 QProcess 对象在返回前等待输出,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41893183/

相关文章:

c++ - 在 C++ 中通过引用和值传递

c++ - QProgressBar随着函数的进展而更新

c++ - 打开和关闭 ODBC 连接导致崩溃

c++ - Qt:信号调用函数的默认参数

c++ - QEvent 信号和槽

c++ - 所有shared_ptr都引用我的 vector 中的同一个指针

c++ - 什么软件在设计/规划一个新的大型个人项目时有用?

ios - 使用 Apple Pencil 流畅绘图

c++ - QCalendarWidget : how to set specific day when changing the month?

c++ - 要求用户制造的容器符合 range-v3