Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/qt/6.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
QProcess的正确使用 平台:Qt 4.8.2,Win 7 请考虑以下逻辑流程: 1. App started 2. functionA() triggered 3. the app periodically capture some images to external files 4. end of functionA() 5. the app create a video from captured images, using ffmpeg as external program 6. [step 2 -> step 5] may be repeated. 7. App quit_Qt_Qprocess - Fatal编程技术网

QProcess的正确使用 平台:Qt 4.8.2,Win 7 请考虑以下逻辑流程: 1. App started 2. functionA() triggered 3. the app periodically capture some images to external files 4. end of functionA() 5. the app create a video from captured images, using ffmpeg as external program 6. [step 2 -> step 5] may be repeated. 7. App quit

QProcess的正确使用 平台:Qt 4.8.2,Win 7 请考虑以下逻辑流程: 1. App started 2. functionA() triggered 3. the app periodically capture some images to external files 4. end of functionA() 5. the app create a video from captured images, using ffmpeg as external program 6. [step 2 -> step 5] may be repeated. 7. App quit,qt,qprocess,Qt,Qprocess,为了实现流程,我使用QProcess启动外部程序来加入图像,但我对QProcess的正确使用模式感到困惑。(我不关心ffmpeg的控制台消息,我通过检查是否创建了视频文件来确定步骤5是否成功。) 尝试1 在(a)中,我阅读了文档,这个调用可以冻结主GUI,那么我应该从QThread/QRunnable调用吗 在(b),我是不是错过了什么?当我尝试关闭应用程序时(流程中的步骤7),应用程序崩溃,我认为生成的QProcess没有正确释放 尝试2 我编写了QProcess的包装类,如下所示: 发射装置

为了实现流程,我使用QProcess启动外部程序来加入图像,但我对QProcess的正确使用模式感到困惑。(我不关心ffmpeg的控制台消息,我通过检查是否创建了视频文件来确定步骤5是否成功。)

尝试1

在(a)中,我阅读了文档,这个调用可以冻结主GUI,那么我应该从QThread/QRunnable调用吗

在(b),我是不是错过了什么?当我尝试关闭应用程序时(流程中的步骤7),应用程序崩溃,我认为生成的QProcess没有正确释放

尝试2

我编写了QProcess的包装类,如下所示:

发射装置

class Launcher : public QObject
{
    Q_OBJECT
public:
    /** constructor */
    explicit Launcher(QObject *parent = 0);
    /** destructor */
    ~Launcher() {
        if (started_ && process_->state() != QProcess::NotRunning)
            process_->kill();
    } // end_dtor(Launcher)
Q_SIGNALS:
    void feedbackLog(QString log);
public Q_SLOTS:
    void launch(QString program, QStringList argList);
private:
    QProcess * process_;
    bool started_;
private Q_SLOTS:
    void error(QProcess::ProcessError error);
    void finished(int exitCode, QProcess::ExitStatus status);
    void stateChanged(QProcess::ProcessState state);
}; // end_class(Launcher)

#endif // LAUNCHER_H
Launcher.cpp

#include "launcher.h"
#include <QCoreApplication>
#include <QtDebug>

Launcher::Launcher(QObject *parent) : QObject(parent), started_(false)
{
    process_ = new QProcess(this);
    connect(process_,
            SIGNAL(error(QProcess::ProcessError)),
            SLOT(error(QProcess::ProcessError)));
    connect(process_,
            SIGNAL(finished(int, QProcess::ExitStatus)),
            SLOT(finished(int, QProcess::ExitStatus)));
    connect(process_,
            SIGNAL(stateChanged(QProcess::ProcessState)),
            SLOT(stateChanged(QProcess::ProcessState)));
} // end_ctor(ExternalLauncher)

void Launcher::launch(QString program, QStringList argList)
{
    started_ = true;
    process_->start(program, argList);
    process_->waitForFinished(-1); // (c)
    Q_EMIT feedbackLog(process_->readAllStandardOutput());
    process_->close();
} // end Launcher::launch()

void Launcher::error(QProcess::ProcessError error)
{
    /* just feedback some text about the error */
} // end_slot(Launcher::error)

void Launcher::finished(int exitCode, QProcess::ExitStatus status)
{
    started_ = false;
    /* feedback some text about finished */
} // end_slot (Launcher::finished)

void Launcher::stateChanged(QProcess::ProcessState state)
{
    qDebug() << "Luancher::stateChanged" << state;
}
那么,在(c)处,是否不需要waitForFinished()?(当我阅读一些信息时,我不应该混淆waitForXXX()和QProcess的信号/插槽框架)

另外,Launcher类中是否有我遗漏的东西,因为在使用这种方法时,我也经历了应用程序崩溃

主要问题:通常,何时调用QProcess::terminate()/QProcess::kill(),何时删除QProcess对象


谢谢

您不需要
waitForFinished()
,您将收到关于它的信号,为什么要等待呢?相反,您可能希望在
launch()
waitForStarted()
,以确保流程已成功启动。当然,在这种情况下,您需要更改使用
启动器的方式
——不要在
launch()之后立即销毁它

如果进程已完成,则不需要
terminate()
/
kill()
该进程,只有在需要提前停止该进程时才需要。您可以在收到
finished()
error()
信号时使用
process->deleteLater()
(您不能在插槽中时仅
删除进程
)或在
~Launcher()
中删除它,前提是在进程完成之前不会调用它

#include "launcher.h"
#include <QCoreApplication>
#include <QtDebug>

Launcher::Launcher(QObject *parent) : QObject(parent), started_(false)
{
    process_ = new QProcess(this);
    connect(process_,
            SIGNAL(error(QProcess::ProcessError)),
            SLOT(error(QProcess::ProcessError)));
    connect(process_,
            SIGNAL(finished(int, QProcess::ExitStatus)),
            SLOT(finished(int, QProcess::ExitStatus)));
    connect(process_,
            SIGNAL(stateChanged(QProcess::ProcessState)),
            SLOT(stateChanged(QProcess::ProcessState)));
} // end_ctor(ExternalLauncher)

void Launcher::launch(QString program, QStringList argList)
{
    started_ = true;
    process_->start(program, argList);
    process_->waitForFinished(-1); // (c)
    Q_EMIT feedbackLog(process_->readAllStandardOutput());
    process_->close();
} // end Launcher::launch()

void Launcher::error(QProcess::ProcessError error)
{
    /* just feedback some text about the error */
} // end_slot(Launcher::error)

void Launcher::finished(int exitCode, QProcess::ExitStatus status)
{
    started_ = false;
    /* feedback some text about finished */
} // end_slot (Launcher::finished)

void Launcher::stateChanged(QProcess::ProcessState state)
{
    qDebug() << "Luancher::stateChanged" << state;
}
void MyWidget::createAVI()
{
    checkAndDeleteAVI();
    launcher_.launch("ffmpeg", "argsList"); // launcher_ defined as class member;
}