Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

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 use app.exec() (not return 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 call QCoreApplication::quit() after the sub-process's finished 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 a VideoHandler 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.



  • @JonB

    1. 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.
    2. 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 using finished 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 into app.exec() and you can just have your return 0; instead. Assuming nothing in your VideoHandler needs a Qt event loop to be running.



  • @JonB I am going to try the QProcess::execute() method. Thanks!


Log in to reply