- Platform: Qt 4.8.2, Win 7
Please consider the following logical stream:
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
To achieve the thread, I use QProcess to run an external program so that I can join the images, but I am confused about the correct use of QProcess. (I do not need ffmpeg console messages, I determine the success of step 5 by checking if the video file is created.)
Attempt 1
void MyWidget::createAVI()
{
checkAndDeleteAVI();
process = new QProcess(this);
process->start("ffmpeg -f images2 ....");
process->waitForFinished(-1);
}
In (a), I read the documentation that this call might freeze the main GUI, so what should I call from QThread / QRunnable?
On (b) did I miss something? as when trying to close the application (step 7 in the stream), the application crashes, and I thought that the generated QProcess was not correctly released.
Attempt 2
I wrote the QProcess shell class as follows:
Launcher.h
class Launcher : public QObject
{
Q_OBJECT
public:
explicit Launcher(QObject *parent = 0);
~Launcher() {
if (started_ && process_->state() != QProcess::NotRunning)
process_->kill();
}
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);
};
#endif
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)));
}
void Launcher::launch(QString program, QStringList argList)
{
started_ = true;
process_->start(program, argList);
process_->waitForFinished(-1);
Q_EMIT feedbackLog(process_->readAllStandardOutput());
process_->close();
}
void Launcher::error(QProcess::ProcessError error)
{
}
void Launcher::finished(int exitCode, QProcess::ExitStatus status)
{
started_ = false;
}
void Launcher::stateChanged(QProcess::ProcessState state)
{
qDebug() << "Luancher::stateChanged" << state;
}
How I use Launcher:
void MyWidget::createAVI()
{
checkAndDeleteAVI();
launcher_.launch("ffmpeg", "argsList"); // launcher_ defined as class member;
}
, (c), ForFinished()? ( , waitForXXX() / QProcess)
, -, Launcher, .
: , QProcess:: terminate()/QProcess:: kill() QProcess?