gpt4 book ai didi

qt - QProcess 的正确使用

转载 作者:行者123 更新时间:2023-12-04 13:30:07 26 4
gpt4 key购买 nike

  • 平台: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 启动外部程序让我加入图像,但我对 QProcess 的正确使用模式感到困惑。 (我不关心 ffmpeg 的控制台消息,我通过检查视频文件是否创建来确定步骤 5 是否成功。)

    尝试 1
    void MyWidget::createAVI()
    {
    checkAndDeleteAVI();
    process = new QProcess(this); // process_ defined as class member;
    process->start("ffmpeg -f images2 ....");
    process->waitForFinished(-1); // (a)
    // (b)
    }

    在 (a) 处,我阅读了此调用可以卡住主 GUI 的文档,所以我应该从 QThread/QRunnable 调用吗?

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

    尝试 2

    我写了一个 QProcess 的包装类如下:

    启动器.h
    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

    启动器.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;
    }

    我如何使用启动器:
    void MyWidget::createAVI()
    {
    checkAndDeleteAVI();
    launcher_.launch("ffmpeg", "argsList"); // launcher_ defined as class member;
    }

    那么,在(c)处,是不是没有必要waitForFinished()? (因为我读了一些信息,我不应该混淆 QProcess 的 waitForXXX() 和信号/插槽框架)

    另外,我在 Launcher 类中是否遗漏了一些东西,因为在使用这种方法时我也遇到了应用程序崩溃。

    主要问题:一般来说,什么时候调用 QProcess::terminate()/QProcess::kill(),什么时候删除 QProcess 对象?

    谢谢

    最佳答案

    你不需要waitForFinished() ,你会收到有关它的信号,所以为什么要等待?相反,您可能想要 waitForStarted()launch()以确保该过程已成功启动。当然,在这种情况下,您需要更改 Launcher 的使用方式。 - 不要在 launch() 之后立即销毁它.

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

    关于qt - QProcess 的正确使用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16296967/

    26 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com