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. Why the main thread is needed for QCoreApplication?
Forum Updated to NodeBB v4.3 + New Features

Why the main thread is needed for QCoreApplication?

Scheduled Pinned Locked Moved General and Desktop
11 Posts 2 Posters 11.8k Views 2 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.
  • D Offline
    D Offline
    Dmitriy Shmykov
    wrote on last edited by
    #1

    When we start QCoreApplication from the thread that differs from the main we see qWarning about it and QCoreApplication::exec returns -1.

    I haven't found any fundamental reasons why QCoreApplication should work only from the main thread. There's such reason for QApplication because many platforms require that GUI must work from the main thread. But what about QCoreApplication?

    Does Qt EventLoop-ing requires to work only from the main thread?I think that there should be QCoreApplication-based solutions that support Qt EventLooping from separate threads. That's so because if there's no way to implement that thing it means that we cannot write libraries based on Qt and use them in projects that have no QApplication objects. But if we could run Qt EventLooping in the separate thread then we can run libraries that interact with non-Qt projects.

    1 Reply Last reply
    0
    • Chris KawaC Offline
      Chris KawaC Offline
      Chris Kawa
      Lifetime Qt Champion
      wrote on last edited by Chris Kawa
      #2

      When we start QCoreApplication from the thread that differs from the main...

      What do you mean by "start the QCoreApplication"? Do you mean the event loop? If so then the restriction is that it has to run in the same thread the QCoreApplication was created in. Btw. that's what Qt calls "main thread" - it's the thread the QCoreApplication was created in and its event loop is run in. It's not necessarily the thread the "main()" of your app runs in.

      So there's no restriction to creating QCoreApplication object in another thread. The restriction is only that its event loop must run in the thread the object was created in. For example this sample runs just fine:

      #include <QCoreApplication>
      #include <QTimer>
      #include <thread>
      
      void runsInOtherThread(int argc, char *argv[])
      {
          QCoreApplication a(argc, argv);
          QTimer::singleShot(1000, &a, &QCoreApplication::quit); //spin for one second and quit
          a.exec();
      }
      
      int main(int argc, char *argv[])
      {
          std::thread t(runsInOtherThread, argc, argv);
          // do some stuff while Qt runs in another thread
          // ...
          t.join();
          return 0;
      }
      
      D 1 Reply Last reply
      3
      • D Offline
        D Offline
        Dmitriy Shmykov
        wrote on last edited by
        #3

        Thank you for reply. I was confused by the terminology in Qt documentation and qWarnings when I ran my code.

        1 Reply Last reply
        0
        • Chris KawaC Chris Kawa

          When we start QCoreApplication from the thread that differs from the main...

          What do you mean by "start the QCoreApplication"? Do you mean the event loop? If so then the restriction is that it has to run in the same thread the QCoreApplication was created in. Btw. that's what Qt calls "main thread" - it's the thread the QCoreApplication was created in and its event loop is run in. It's not necessarily the thread the "main()" of your app runs in.

          So there's no restriction to creating QCoreApplication object in another thread. The restriction is only that its event loop must run in the thread the object was created in. For example this sample runs just fine:

          #include <QCoreApplication>
          #include <QTimer>
          #include <thread>
          
          void runsInOtherThread(int argc, char *argv[])
          {
              QCoreApplication a(argc, argv);
              QTimer::singleShot(1000, &a, &QCoreApplication::quit); //spin for one second and quit
              a.exec();
          }
          
          int main(int argc, char *argv[])
          {
              std::thread t(runsInOtherThread, argc, argv);
              // do some stuff while Qt runs in another thread
              // ...
              t.join();
              return 0;
          }
          
          D Offline
          D Offline
          Dmitriy Shmykov
          wrote on last edited by
          #4

          @Chris-Kawa But there's still the warning: "WARNING: QApplication was not created in the main() thread."

          1 Reply Last reply
          0
          • Chris KawaC Offline
            Chris KawaC Offline
            Chris Kawa
            Lifetime Qt Champion
            wrote on last edited by
            #5

            Do you mean my example is giving you this warning or you get it in your app?

            D 1 Reply Last reply
            0
            • Chris KawaC Chris Kawa

              Do you mean my example is giving you this warning or you get it in your app?

              D Offline
              D Offline
              Dmitriy Shmykov
              wrote on last edited by
              #6

              @Chris-Kawa In my app. Example is ok. Maybe I've missed something. Creating and exec-ing QCoreApplication in another thread and still getting the warning.

              1 Reply Last reply
              0
              • Chris KawaC Offline
                Chris KawaC Offline
                Chris Kawa
                Lifetime Qt Champion
                wrote on last edited by
                #7

                Couple of things to check:
                Make sure you don't have any static QObjects (which is bad even in single thread anyway).
                Make sure you're not instantiating any QObjects before the app object is created (in any thread!). This also means that you can't for example create QCoreApplication object in a thread managed by QThread object.

                D 1 Reply Last reply
                0
                • Chris KawaC Chris Kawa

                  Couple of things to check:
                  Make sure you don't have any static QObjects (which is bad even in single thread anyway).
                  Make sure you're not instantiating any QObjects before the app object is created (in any thread!). This also means that you can't for example create QCoreApplication object in a thread managed by QThread object.

                  D Offline
                  D Offline
                  Dmitriy Shmykov
                  wrote on last edited by
                  #8

                  @Chris-Kawa I've found single threaded solution that's suitable for me.

                  I used temporary QCoreApplication object like this.

                  int argc = 0;
                  char** argv = nullptr;
                  QCoreApplication qtApp(argc, argv);
                  Internal::FactoryWorker worker;
                  QObject::connect(&worker, SIGNAL(doWork(cocos2d::Node*, const QString&)), &worker, SLOT(onDoWork(cocos2d::Node*, const QString&)), Qt::QueuedConnection);
                  QObject::connect(&worker, SIGNAL(doWork(cocos2d::Node*, const QString&)), &qtApp,  SLOT(quit()), Qt::QueuedConnection);
                  worker.doWork(parentNode, fileName);
                  qtApp.exec();
                  
                  1 Reply Last reply
                  0
                  • Chris KawaC Offline
                    Chris KawaC Offline
                    Chris Kawa
                    Lifetime Qt Champion
                    wrote on last edited by
                    #9

                    In that case there's no need for the connects or event loop, since all you do in it is start onDoWork and immediately after it quit the loop.
                    Would be the same if you did:

                    int argc = 0;
                    char** argv = nullptr;
                    QCoreApplication qtApp(argc, argv);
                    Internal::FactoryWorker().OnDoWork(parentNode, fileName);
                    
                    D 1 Reply Last reply
                    0
                    • Chris KawaC Chris Kawa

                      In that case there's no need for the connects or event loop, since all you do in it is start onDoWork and immediately after it quit the loop.
                      Would be the same if you did:

                      int argc = 0;
                      char** argv = nullptr;
                      QCoreApplication qtApp(argc, argv);
                      Internal::FactoryWorker().OnDoWork(parentNode, fileName);
                      
                      D Offline
                      D Offline
                      Dmitriy Shmykov
                      wrote on last edited by
                      #10

                      @Chris-Kawa The code into the OnDoWork relies on event loop so I should use it. OnDoWork contains parts of QtCreator modified by me for the project purposes.

                      1 Reply Last reply
                      0
                      • Chris KawaC Offline
                        Chris KawaC Offline
                        Chris Kawa
                        Lifetime Qt Champion
                        wrote on last edited by
                        #11

                        But you quit the loop right after the call to onDoWork, so I assume onDoWork is blocking (otherwise it makes no sense).
                        If onDoWork is blocking then there's no loop processing anyway until it finishes, at which point the loop quits (because of the second connect). Am I missing something? Event processing doesn't happen when you're in a blocking function in a single threaded execution.

                        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