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 12.1k 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.
  • 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