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 848 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 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();
        }
    }
    
    jsulmJ KroMignonK 2 Replies Last reply
    0
    • R Rufledore

      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();
          }
      }
      
      jsulmJ Offline
      jsulmJ Offline
      jsulm
      Lifetime Qt Champion
      wrote on 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 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?

        JonBJ jsulmJ KroMignonK 3 Replies Last reply
        0
        • R Rufledore

          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?

          JonBJ Offline
          JonBJ Offline
          JonB
          wrote on 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

            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?

            jsulmJ Offline
            jsulmJ Offline
            jsulm
            Lifetime Qt Champion
            wrote on 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
            0
            • R Rufledore

              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?

              KroMignonK Offline
              KroMignonK Offline
              KroMignon
              wrote on 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
              • jsulmJ jsulm

                @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 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

                  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();
                      }
                  }
                  
                  KroMignonK Offline
                  KroMignonK Offline
                  KroMignon
                  wrote on 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 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.

                    KroMignonK 1 Reply Last reply
                    0
                    • R Rufledore

                      @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.

                      KroMignonK Offline
                      KroMignonK Offline
                      KroMignon
                      wrote on 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 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

                        • Login

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