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

时间:2017-01-27 11:41:41

标签: c++ qt signals-slots qprocess

注意:标题不能准确传达问题,可以根据需要自由编辑

  1. 关于课程和描述的信息
  2. 问题
  3. 代码示例等
  4. TL; DR
  5. 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如何工作,它将 返回:“你好......”

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

    $ 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并将其分配给{{ 1}} for accessor方法):

    gen_serv

    然而执行此操作,QObject::connect(m, SIGNAL(finishedSignal()), this, SLOT(getResults())); 返回runCommand(),其中main.cpp立即调用qDebug(),qDebug()将输出:

    gen_proc->_proc_out

    4。 TL; DR

    我需要什么:

    我需要设计一个在/替换连接之后运行的方法(在_gen_proc->_proc_out = "" _gen_proc->exitcode = -1 中)。

    此方法将一直等到信号发出,因此调用gen_serv的{​​{1}}将不会返回,直到runCommand()发出QProcess.start()为止,因此保证有效的输出/退出代码值。

    有什么建议吗?

1 个答案:

答案 0 :(得分:1)

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

可能的解决方案(使用QProcess::wait*()&#39; s)

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

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();
    }
}

解决方案非常简单,但是,我将提供一个简短的描述:

  • 首先,检查进程是否实际开始。如果没有,则显示带有错误字符串的相应消息。

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

  

&#34; exec p :没有这样的文件或目录通常意味着找不到program

即。错误的路径或有多余的参数或应用程序不接受任何参数

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

viewRender: function( view, element ) { if (view.name == 'timeline7Days') { $("th[data-date]").each(function(){ $(this).find('span').text(moment($(this).data().date).format('ddd M/D')); }); } } 的原因是此方法等待QProcess :: finished(int)信号。

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

希望这有助于某人