Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. Same application executed as console app or QML GUI
Forum Updated to NodeBB v4.3 + New Features

Same application executed as console app or QML GUI

Scheduled Pinned Locked Moved Unsolved General and Desktop
11 Posts 5 Posters 818 Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • R Offline
    R Offline
    Rufledore
    wrote on 19 Nov 2021, 08:11 last edited by
    #1

    Hello,
    I am looking for a way to make my app executable either as a terminal application or as a QML GUI app (depends on the user preferences).
    My problem is that with my current main.cpp (code is below) when I try to execute the exe as a GUI it also opens the terminal/Windows console.
    I have checked for a solution and I found that I should add the following in CMakeLists:

    if (WIN32)
        set_property(TARGET Ptc05Manager PROPERTY WIN32_EXECUTABLE true)
    else ()
        set_property(TARGET Ptc05Manager PROPERTY WIN32_EXECUTABLE false)
    endif ()
    

    In that way the terminal is not opened together with the GUI, but there is another problem that here when I start the app from the terminal with options the output is not printed in the terminal but in a popup dialog box.

    main.cpp

    int main(int argc, char *argv[])
    {
        bool hasUi = false;
        if (argc > 1) {
            hasUi = false;
        } else {
            hasUi = true;
        }
    
        if (hasUi) {
            QGuiApplication guiApp(argc, argv);
            QQmlApplicationEngine engine;
            GuiConext guiContext;
    
            auto rootContext = engine.rootContext();
            rootContext->setContextProperty("Gui", &guiContext);
    
            // This adds the QML library that is used for the GUI.
            engine.addImportPath(QString("qrc:/"));
            MaterialPlugin materialPlugin;
            materialPlugin.registerTypes("Material");
    
            engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
    
            return guiApp.exec();
        } else {
            // The application runs as terminal app.
            QCoreApplication coreApp(argc, argv);
            int status = 0;
    
    //The following is because there is a need for EventLoop to be executed in the console application.
            QTimer::singleShot(0, [&]()
            {
                {
                    TerminalRunner runner(&coreApp);
    
                    if (!runner.setUpPtcManager()) {
                        status = 1;
                        coreApp.exit(status);
                        return;
                    }
    
                    runner.uploadConfiguration();
                }
                coreApp.exit(status);
            });
            return coreApp.exec();
        }
    }
    
    J K 2 Replies Last reply 19 Nov 2021, 08:17
    0
    • R Rufledore
      19 Nov 2021, 08:11

      Hello,
      I am looking for a way to make my app executable either as a terminal application or as a QML GUI app (depends on the user preferences).
      My problem is that with my current main.cpp (code is below) when I try to execute the exe as a GUI it also opens the terminal/Windows console.
      I have checked for a solution and I found that I should add the following in CMakeLists:

      if (WIN32)
          set_property(TARGET Ptc05Manager PROPERTY WIN32_EXECUTABLE true)
      else ()
          set_property(TARGET Ptc05Manager PROPERTY WIN32_EXECUTABLE false)
      endif ()
      

      In that way the terminal is not opened together with the GUI, but there is another problem that here when I start the app from the terminal with options the output is not printed in the terminal but in a popup dialog box.

      main.cpp

      int main(int argc, char *argv[])
      {
          bool hasUi = false;
          if (argc > 1) {
              hasUi = false;
          } else {
              hasUi = true;
          }
      
          if (hasUi) {
              QGuiApplication guiApp(argc, argv);
              QQmlApplicationEngine engine;
              GuiConext guiContext;
      
              auto rootContext = engine.rootContext();
              rootContext->setContextProperty("Gui", &guiContext);
      
              // This adds the QML library that is used for the GUI.
              engine.addImportPath(QString("qrc:/"));
              MaterialPlugin materialPlugin;
              materialPlugin.registerTypes("Material");
      
              engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
      
              return guiApp.exec();
          } else {
              // The application runs as terminal app.
              QCoreApplication coreApp(argc, argv);
              int status = 0;
      
      //The following is because there is a need for EventLoop to be executed in the console application.
              QTimer::singleShot(0, [&]()
              {
                  {
                      TerminalRunner runner(&coreApp);
      
                      if (!runner.setUpPtcManager()) {
                          status = 1;
                          coreApp.exit(status);
                          return;
                      }
      
                      runner.uploadConfiguration();
                  }
                  coreApp.exit(status);
              });
              return coreApp.exec();
          }
      }
      
      J Offline
      J Offline
      jsulm
      Lifetime Qt Champion
      wrote on 19 Nov 2021, 08:17 last edited by
      #2

      @Rufledore said in Same application executed as console app or QML GUI:

      //The following is because there is a need for EventLoop to be executed in the console application.

      Why? return coreApp.exec(); starts the event loop.

      "the output is not printed in the terminal but in a popup dialog box." - what output and how do you output it?

      https://forum.qt.io/topic/113070/qt-code-of-conduct

      1 Reply Last reply
      0
      • R Offline
        R Offline
        Rufledore
        wrote on 19 Nov 2021, 08:34 last edited by
        #3

        Why? return coreApp.exec(); starts the event loop.

        coreApp.exec() is called in the end of the main function but I need some things to be executed after the event loop is started and that's my way.

        The console output is printed with std::cout.
        Please stick to the topic. Do you have any idea how to help me?

        J J K 3 Replies Last reply 19 Nov 2021, 08:36
        0
        • R Rufledore
          19 Nov 2021, 08:34

          Why? return coreApp.exec(); starts the event loop.

          coreApp.exec() is called in the end of the main function but I need some things to be executed after the event loop is started and that's my way.

          The console output is printed with std::cout.
          Please stick to the topic. Do you have any idea how to help me?

          J Offline
          J Offline
          JonB
          wrote on 19 Nov 2021, 08:36 last edited by
          #4

          @Rufledore said in Same application executed as console app or QML GUI:

          Please stick to the topic. Do you have any idea how to help me?

          He is trying to help you.

          1 Reply Last reply
          0
          • R Rufledore
            19 Nov 2021, 08:34

            Why? return coreApp.exec(); starts the event loop.

            coreApp.exec() is called in the end of the main function but I need some things to be executed after the event loop is started and that's my way.

            The console output is printed with std::cout.
            Please stick to the topic. Do you have any idea how to help me?

            J Offline
            J Offline
            jsulm
            Lifetime Qt Champion
            wrote on 19 Nov 2021, 08:42 last edited by
            #5

            @Rufledore said in Same application executed as console app or QML GUI:

            Please stick to the topic

            Where was I off-topic?
            Also, pointing to issues not related to original question isn't a bad thing in my opinion. I always appreciate if others point out issues in my code even if not related to original question.

            OK, what you are doing with the timer is fine.

            I don't see how std::cout output would end-up in a dialog box, unless you implement it by yourself.
            Without seeing the code I can't tell more.

            https://forum.qt.io/topic/113070/qt-code-of-conduct

            R 1 Reply Last reply 19 Nov 2021, 10:11
            0
            • R Rufledore
              19 Nov 2021, 08:34

              Why? return coreApp.exec(); starts the event loop.

              coreApp.exec() is called in the end of the main function but I need some things to be executed after the event loop is started and that's my way.

              The console output is printed with std::cout.
              Please stick to the topic. Do you have any idea how to help me?

              K Offline
              K Offline
              KroMignon
              wrote on 19 Nov 2021, 08:50 last edited by
              #6

              @Rufledore said in Same application executed as console app or QML GUI:

              Please stick to the topic. Do you have any idea how to help me?

              Please take time to understand the question asked.
              In your code there is a strange comment: The following is because there is a need for EventLoop to be executed in the console application.

              But, as @jsulm already has written, calling coreApp.exec() will already start an eventloop.

              You code don't made sense:
              Simple change you code to something like this:

              // The application runs as terminal app.
              QCoreApplication coreApp(argc, argv);
              int status = 0;
              
              TerminalRunner runner(&coreApp);
              
              // stop application when runner is done
              QObject::connect(&runner, &TerminalRunner::done, &coreApp, &QCoreApplication::quit);
              // call TerminalRunner start slot asap
              QTimer::singleShot(0, &runner, &TerminalRunner::start);
              
              // start event loop and wait until finished
              return coreApp.exec();
              

              Note: I suppose here that your TerminalRunner class has a signal called done() which is emitted when all is done and a slot called start() which has to be called to start processing.

              It is an old maxim of mine that when you have excluded the impossible, whatever remains, however improbable, must be the truth. (Sherlock Holmes)

              1 Reply Last reply
              1
              • J jsulm
                19 Nov 2021, 08:42

                @Rufledore said in Same application executed as console app or QML GUI:

                Please stick to the topic

                Where was I off-topic?
                Also, pointing to issues not related to original question isn't a bad thing in my opinion. I always appreciate if others point out issues in my code even if not related to original question.

                OK, what you are doing with the timer is fine.

                I don't see how std::cout output would end-up in a dialog box, unless you implement it by yourself.
                Without seeing the code I can't tell more.

                R Offline
                R Offline
                Rufledore
                wrote on 19 Nov 2021, 10:11 last edited by
                #7

                @jsulm said in Same application executed as console app or QML GUI:

                I don't see how std::cout output would end-up in a dialog box, unless you implement it by yourself.
                Without seeing the code I can't tell more.

                Like that: Capture.PNG

                With WIN32_EXECUTABLE false it is like that: Capture.PNG

                1 Reply Last reply
                0
                • R Rufledore
                  19 Nov 2021, 08:11

                  Hello,
                  I am looking for a way to make my app executable either as a terminal application or as a QML GUI app (depends on the user preferences).
                  My problem is that with my current main.cpp (code is below) when I try to execute the exe as a GUI it also opens the terminal/Windows console.
                  I have checked for a solution and I found that I should add the following in CMakeLists:

                  if (WIN32)
                      set_property(TARGET Ptc05Manager PROPERTY WIN32_EXECUTABLE true)
                  else ()
                      set_property(TARGET Ptc05Manager PROPERTY WIN32_EXECUTABLE false)
                  endif ()
                  

                  In that way the terminal is not opened together with the GUI, but there is another problem that here when I start the app from the terminal with options the output is not printed in the terminal but in a popup dialog box.

                  main.cpp

                  int main(int argc, char *argv[])
                  {
                      bool hasUi = false;
                      if (argc > 1) {
                          hasUi = false;
                      } else {
                          hasUi = true;
                      }
                  
                      if (hasUi) {
                          QGuiApplication guiApp(argc, argv);
                          QQmlApplicationEngine engine;
                          GuiConext guiContext;
                  
                          auto rootContext = engine.rootContext();
                          rootContext->setContextProperty("Gui", &guiContext);
                  
                          // This adds the QML library that is used for the GUI.
                          engine.addImportPath(QString("qrc:/"));
                          MaterialPlugin materialPlugin;
                          materialPlugin.registerTypes("Material");
                  
                          engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
                  
                          return guiApp.exec();
                      } else {
                          // The application runs as terminal app.
                          QCoreApplication coreApp(argc, argv);
                          int status = 0;
                  
                  //The following is because there is a need for EventLoop to be executed in the console application.
                          QTimer::singleShot(0, [&]()
                          {
                              {
                                  TerminalRunner runner(&coreApp);
                  
                                  if (!runner.setUpPtcManager()) {
                                      status = 1;
                                      coreApp.exit(status);
                                      return;
                                  }
                  
                                  runner.uploadConfiguration();
                              }
                              coreApp.exit(status);
                          });
                          return coreApp.exec();
                      }
                  }
                  
                  K Offline
                  K Offline
                  KroMignon
                  wrote on 19 Nov 2021, 10:25 last edited by
                  #8

                  @Rufledore said in Same application executed as console app or QML GUI:

                  set_property(TARGET Ptc05Manager PROPERTY WIN32_EXECUTABLE true)

                  This is to force the creation of a Windows application without console.
                  So what did you expect what happen when using this?

                  It is an old maxim of mine that when you have excluded the impossible, whatever remains, however improbable, must be the truth. (Sherlock Holmes)

                  1 Reply Last reply
                  0
                  • R Offline
                    R Offline
                    Rufledore
                    wrote on 19 Nov 2021, 10:48 last edited by
                    #9

                    @KroMignon said in Same application executed as console app or QML GUI:

                    So what did you expect what happen when using this?

                    I would like to have an app that executes as a console application when it is started with parameters and as a GUI when it is started without parameters e.g. the icon or in console. Everything works fine usually except the fact that when I start the GUI from the icon a console is opened too and I don't wont that to happen. The solution that I found was to set WIN32_EXECUTABLE to true, but that stops the console app behavior. So, I would like to find a working solution.

                    K 1 Reply Last reply 19 Nov 2021, 10:54
                    0
                    • R Rufledore
                      19 Nov 2021, 10:48

                      @KroMignon said in Same application executed as console app or QML GUI:

                      So what did you expect what happen when using this?

                      I would like to have an app that executes as a console application when it is started with parameters and as a GUI when it is started without parameters e.g. the icon or in console. Everything works fine usually except the fact that when I start the GUI from the icon a console is opened too and I don't wont that to happen. The solution that I found was to set WIN32_EXECUTABLE to true, but that stops the console app behavior. So, I would like to find a working solution.

                      K Offline
                      K Offline
                      KroMignon
                      wrote on 19 Nov 2021, 10:54 last edited by KroMignon
                      #10

                      @Rufledore said in Same application executed as console app or QML GUI:

                      The solution that I found was to set WIN32_EXECUTABLE to true, but that stops the console app behavior. So, I would like to find a working solution.

                      This is not the solution, is will only allow/disable the Windows application to create a Console.
                      If there is not console, there will be a Window which will be created to show the stdout message.

                      You can hide console on application startup with something like this:

                      HWND hWnd = GetConsoleWindow();
                      ShowWindow( hWnd, SW_HIDE );
                      

                      Of course, this only works for Windows

                      It is an old maxim of mine that when you have excluded the impossible, whatever remains, however improbable, must be the truth. (Sherlock Holmes)

                      1 Reply Last reply
                      0
                      • S Offline
                        S Offline
                        SimonSchroeder
                        wrote on 22 Nov 2021, 09:10 last edited by
                        #11

                        Windows does not support the same application to be both a console and a GUI app. The major problem is that a GUI application should not have an attached console and a console application should use an existing console when started from the command line instead of opening a new one. This is not possible on Windows.

                        Here is the next best thing you can do on Windows (I have read that Microsoft's own devenv command does it this way): Compile your application both as .exe (GUI application) and .com (console/command line application). This can be done from the same source code if you use a few #ifdef's. If you have a myapp.exe and a myapp.com and type myapp (without the file extension) on the command line, Windows will do the right thing. In our own application we provided an option to specify you want the GUI. If the console app was started with the GUI option it will just use QProcess to launch the GUI version and exit.

                        Here is a short snippet with the most important information how we do it:

                        // Windows header
                        #include <windows.h>
                        #include <consoleapi.h>
                        
                        #ifdef _MSC_VER
                        #pragma warning(push)
                        #pragma warning(disable : 4100)     // false warning of unused parameter 'a'
                        #endif
                        void startGui(QApplication &a)
                        {
                            QString currentDir = QDir::currentPath();
                            QStringList arguments = a.arguments();
                            arguments.removeFirst();
                            QDir::setCurrent(QCoreApplication::applicationDirPath());
                            QProcess::startDetached(QFileInfo(QCoreApplication::applicationFilePath()).completeBaseName() + ".exe",
                                                    arguments, currentDir);
                        }
                        #ifdef _MSC_VER
                        #pragma warning(pop)
                        #endif
                        
                        void openConsole()
                        {
                            AllocConsole();
                            std::freopen( "CON", "w", stdout );
                            std::freopen( "CON", "w", stderr );
                            std::freopen( "CON", "r", stdin );
                        }
                        
                        int main(int argc, char *argv[])
                        {
                            QApplication a(argc, argv);
                        
                            CommandLineArgs args = parseCommandLine(a);
                        
                        #ifdef CONSOLE_APP
                            if(args.gui)
                            {
                                startGui(a);
                                return 0;
                            }
                        #else
                            if(args.gui)
                            {
                                QString filename;
                        
                                Dialog w(filename);
                                w.show();
                                return a.exec();
                            }
                        
                            openConsole();
                        #endif
                        
                            return processWithArgs(args);
                        }
                        

                        The difference is that we don't have an event loop when run as a pure console application.

                        1 Reply Last reply
                        0

                        1/11

                        19 Nov 2021, 08:11

                        • Login

                        • Login or register to search.
                        1 out of 11
                        • First post
                          1/11
                          Last post
                        0
                        • Categories
                        • Recent
                        • Tags
                        • Popular
                        • Users
                        • Groups
                        • Search
                        • Get Qt Extensions
                        • Unsolved