Creating a Qt command line application using QProcess
-
Hi,
For these days I have been working on a Qt application to process video files. My app will work from the command line, and it will have this basic structure:- main.cpp will call an instance of my class VideoHandler
- The class VideoHandler will instance a QProcess variable to run an external command, which makes the operation I need to the video file. As soon as the external process is done, I need to finish my Qt application.
Now, what I want to know is this: what is the more elegant way to handle the result of an external process, so I can finish my app in a clean way after the process is done.
I was trying something like this from the main.cpp file:
int main(int argc, char *argv[]) { QCoreApplication app(argc, argv); QString videoFile = "C:/path/to/video.mp4" VideoHandler *handler = new VideoHandler(videoFile); return app.exec(); }
The QProcess operation inside the VideoHandler class works like a charm, but my Qt application never ends. I was thinking of using the method QCoreApplication::quit() after I catch the finished() signal from QProcess.. but is this the better way to do it?
On the other hand, I tried to use the line "return 0;" instead of "return app.exec()". In that case, the Qt application ends as I need it, but the VideoHandler class doesn't process the video at all. So, I appreciate any advice on this matter.
Thanks!
-
@xtingray
Your program is just a normal GUI process. You must useapp.exec()
(notreturn 0;
) to run its GUI, else as you say the video handler won't be shown.The fact that you somewhere run a
QProcess
sub-process is neither here nor there. Your program will exit when its last open window is closed, or as you say you could indeed callQCoreApplication::quit()
after the sub-process'sfinished
signal is received. -
@JonB I am a little lost here. My application is just a console command line, I mean, there is no GUI to show, there are no windows to show. I run the command from the console, the program modifies the video, and that's it. Think of my program as a Unix command line.
PS: If you pay attention to the source code, I use the class QCoreApplication instead of the QApplication class. Quoting from the Qt documentation: "This class is used by non-GUI applications to provide their event loop."
-
@xtingray
OK I understand. But then I don't understand how you can have aVideoHandler
class, I assumed that is a UI component...?On the other hand, I tried to use the line "return 0;" instead of "return app.exec()". In that case, the Qt application ends as I need it, but the VideoHandler class doesn't process the video at all.
So what does it do?
The class VideoHandler will instance a QProcess variable to run an external command
Where, when? All I see is a constructor.
I was thinking of using the method QCoreApplication::quit() after I catch the finished() signal from QProcess.. but is this the better way to do it?
So does that do what you want it to? Seems not unreasonable to me if that is what you require. If you want to wait for a
QProcess
to complete and then quit. -
- The VideoHandler is a QObject class. It doesn't have any UI component. And yes, you can create a complete Qt application without using any GUI element.
- The VideoHandler just creates an instance of a QProcess object to call an external command. When the command ends, the QProcess emits the finished() signal and then I call the QCoreApplication::quit() method.
In fact, the structure of the project is very basic. All I am looking for, it's just the feedback of someone who already had made console applications like this before, to find out if there are better ways to do it. That's it.
-
@xtingray
So I don't see any problem with usingfinished
signal, as discussed.However, If you don't want to have to write a slot, you could use
QProcess::execute()
, https://doc.qt.io/qt-5/qprocess.html#execute, which blocks until finished for you. That seems to work fine without having to enter the Qt event loop (tested), so it itself should not require you to go intoapp.exec()
and you can just have yourreturn 0;
instead. Assuming nothing in yourVideoHandler
needs a Qt event loop to be running.