qt定期检查QProcess状态

时间:2016-05-20 08:35:43

标签: c++ qt

我从文本文件中启动多个QProcesses(例如notepad.exe等不同的程序),并且想要定期检查它们是否仍在运行。

while循环不是解决方案,因为它阻止了ui-thread。 怎么能实现这一目标?在Java(Android)中,我会用asynctask来做这件事 连接到ScheduldExecutorService。类似的东西可用于qt吗?

这是我开始流程的地方:

void mywidget::startprocesses(QString &text)
{
    QProcess *process = new QProcess(this);
    this->myprocess.append(process);
    process->start(text);
    int state = process->state();
    addlabelstatus(state);
}

这里的方法叫做:

while(!stream->atEnd())                                    //check stream until empty and assign line as a caption to a new QLabel
        {
            this->fileread = stream->readLine();
            if(!this->fileread.isEmpty())
            {
                central->addlabel(this->fileread);
                central->startprocesses(this->fileread);
            }
        }






void mywidget::addlabelstatus(QProcess::ProcessState newstate)
{
    QString sstring;

    if(newstate == 0)
    {
        QString sstring = "Wird nicht ausgeführt";
        QLabel *label = new QLabel(sstring);
        this->processstatus.append(label);
        this->vrarea->addWidget(label);
    }
    else if (newstate == 1)
    {
        QString sstring = "Wird gestartet!";
        QLabel *label = new QLabel(sstring);
        this->processstatus.append(label);
        this->vrarea->addWidget(label);
    }
    else if (newstate == 2)
    {
        QString sstring = "Wird ausgeführt!";
        QLabel *label = new QLabel(sstring);
        this->processstatus.append(label);
        this->vrarea->addWidget(label);
    }
    else
    {
        QString sstring = "kein Status vorhanden!";
        QLabel *label = new QLabel(sstring);
        this->processstatus.append(label);
        this->vrarea->addWidget(label);
    }
}

2 个答案:

答案 0 :(得分:4)

每个QProcess都有finished(int exitCode, QProcess::ExitStatus exitStatus)stateChanged(QProcess::ProcessState newState)个信号,这些信号在某个进程终止或更改时(按类型)发出。所以你的代码可以是:

.H方:

public slots:
    void processFinished(int exitCode, QProcess::ExitStatus exitStatus);
    void addlabelstatus(QProcess::ProcessState newState);

.CPP方:

void mywidget::processFinished(int exitCode, QProcess::ExitStatus exitStatus)
{
    <...>
}

void mywidget::addlabelstatus(QProcess::ProcessState newState)
{
    switch(newState) {
        <...>
    };
}

// Your code change

QProcess *process = new QProcess(this);
this->myprocess.append(process);
connect(process, &QProcess::finished, this, &mywidget::processFinished);
connect(process, &QProcess::stateChanged, this, &mywidget::addlabelstatus);
process->start(text);

评论问题的更新

您可以尝试这种方式:

.H方

public slots:
    void processFinished(QLabel *label, int exitCode, QProcess::ExitStatus exitStatus);
    void addlabelstatus(QLabel *label, QProcess::ProcessState newState);

.CPP方

void mywidget::processFinished(QLabel *label, int exitCode, QProcess::ExitStatus exitStatus)
{
    <...>
}

void mywidget::addlabelstatus(QLabel *label, QProcess::ProcessState newState)
{
    switch(newState) {
        <...>
    };
}

while(!stream->atEnd()) {
            this->fileread = stream->readLine();
            if(!this->fileread.isEmpty()) {
                QLabel *label = new QLabel(this->fileread);
                QProcess *process = new QProcess(this);
                this->myprocess.append(process);

                connect(process, &QProcess::finished, [=] 
                (int exitCode, QProcess::ExitStatus exitStatus) 
                { processFinished(label, exitCode, exitStatus); });

                connect(process, &QProcess::stateChanged, [=] 
                (QProcess::ProcessState newState) 
                { addlabelstatus(label, newState); });

                process->start(text);
            }
}

答案 1 :(得分:2)

  

while循环不是解决方案,因为它阻止了ui-thread。

正确。但是,由于Qt是一个事件驱动的框架,您可以使用计时器: -

// Assuming we have a list of processes QList<QProcess*> called timerList

QTimer* pTimer = new QTimer;
connect(pTimer, &QTimer::timeout, [=](){

    foreach(QProcess* proc, timerList)
    {
        // get state
        int state = process->state();
        // update UI
        addlabelstatus(state);            
    }

});

pTimer->start(1000); // every second

或者,当@someoneinthebox回答时,连接到每个QProcess的stateChanged信号,以便在发生时通知您并对此作出反应。