- Платформа: Qt 4.8.2, Win 7
Пожалуйста, обратите внимание на следующую логическую схему:Правильное использование QProcess
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)
}
В (а), Я прочитал документацию, что этот вызов может заморозить главный графический интерфейс, так что я должен позвонить из QThread/QRunnable?
На (б) я что-то пропустил? как при попытке закрыть приложение (шаг 7 в потоке), приложение падает, и я думал, что порожденный QProcess не был правильно выпущен.
Покушение 2
Я написал класс обертку QProcess следующим образом:
Launcher.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
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;
}
Как использовать Пусковая установка:
void MyWidget::createAVI()
{
checkAndDeleteAVI();
launcher_.launch("ffmpeg", "argsList"); // launcher_ defined as class member;
}
Итак, в (c), нет необходимости ждатьForFinished()? (поскольку я прочитал некоторую информацию о том, что мне не следует смешивать waitForXXX() и структуру сигнальных/слотов для QProcess)
Кроме того, есть ли что-то, что я пропустил для класса Launcher, так как у меня также наблюдается крушение приложения при использовании этого подхода.
Главный вопрос: В общем случае, когда нужно вызвать QProcess :: terminate()/QProcess :: kill() и когда удалить объект QProcess?
Благодарности