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. Running gui in thread other than main thread - QObject error: Timers cannot be stopped from another thread

Running gui in thread other than main thread - QObject error: Timers cannot be stopped from another thread

Scheduled Pinned Locked Moved Unsolved General and Desktop
3 Posts 2 Posters 2.2k Views
  • 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.
  • S Offline
    S Offline
    skebanga
    wrote on last edited by
    #1

    At work we have an application framework which does a bunch of stuff all our apps are required to do, such as initialising the logging framework, signal handlers etc, after which the main thread enters into a reactor loop to handle async IO.

    I'm trying to develop a Qt gui app within this framework.

    given our application framework takes main thread for its reactor, I am trying to use a separate thread for Qt.

    void onStart() override
    {
    	gui_thread_ = std::thread([&](){ guiThread(); });
    }
    

    In the gui thread I create a QApplication object, and store it in a std::unique_ptr (so that when the thread completes, the QApplication will be destroyed)

    void guiThread()
    {
    	auto app = std::make_unique<QApplication>(argc_, argv_);
    
    	AppMainWindow* w = new AppMainWindow(); // QMainWindow subclass
    	w->show();
    
    	app->exec();                            // enters QApplication event loop
    
    	asyncShutdown();                        // breaks main thread's reactor loop
    
    	LOG("gui thread exit);
    }
    

    The problem that I'm having is that when the QApplication is destructed (at guiThread function scope exit), I get an error on stderr

    QObject::~QObject: Timers cannot be stopped from another thread

    Below is an excerpt from our log.

    The 2nd column is thread-id, and you can see that thread 1 is the gui thread, and thread 0 is the main thread.

    You can also see the destruction of QMainWindow and QApplication occurs on the gui thread.

    |11:24:03.105| [1] [AppMainWindow::~AppMainWindow] main.window: 
    |11:24:03.106| [1] [Reactor::asyncShutdown] Initiating async shutdown
    |11:24:03.107| [1] [App::guiThread] gui thread exit
    QObject::~QObject: Timers cannot be stopped from another thread
    |11:24:03.254| [0] [Reactor::breakLoop] reactor stopped
    

    I don't use QTimer anywhere in my code, so I suppose this is a timer somewhere in the Qt framework itself.

    I have also tried destroying the QApplication from main thread, but that causes a segmentation fault.

    Questions:

    • What exactly is causing this error?
    • Is running Qt applications on a thread other than main-thread viable?
    • How can I tear down QApplication etc safely, without having these kinds of errors?
    kshegunovK 1 Reply Last reply
    0
    • S skebanga

      At work we have an application framework which does a bunch of stuff all our apps are required to do, such as initialising the logging framework, signal handlers etc, after which the main thread enters into a reactor loop to handle async IO.

      I'm trying to develop a Qt gui app within this framework.

      given our application framework takes main thread for its reactor, I am trying to use a separate thread for Qt.

      void onStart() override
      {
      	gui_thread_ = std::thread([&](){ guiThread(); });
      }
      

      In the gui thread I create a QApplication object, and store it in a std::unique_ptr (so that when the thread completes, the QApplication will be destroyed)

      void guiThread()
      {
      	auto app = std::make_unique<QApplication>(argc_, argv_);
      
      	AppMainWindow* w = new AppMainWindow(); // QMainWindow subclass
      	w->show();
      
      	app->exec();                            // enters QApplication event loop
      
      	asyncShutdown();                        // breaks main thread's reactor loop
      
      	LOG("gui thread exit);
      }
      

      The problem that I'm having is that when the QApplication is destructed (at guiThread function scope exit), I get an error on stderr

      QObject::~QObject: Timers cannot be stopped from another thread

      Below is an excerpt from our log.

      The 2nd column is thread-id, and you can see that thread 1 is the gui thread, and thread 0 is the main thread.

      You can also see the destruction of QMainWindow and QApplication occurs on the gui thread.

      |11:24:03.105| [1] [AppMainWindow::~AppMainWindow] main.window: 
      |11:24:03.106| [1] [Reactor::asyncShutdown] Initiating async shutdown
      |11:24:03.107| [1] [App::guiThread] gui thread exit
      QObject::~QObject: Timers cannot be stopped from another thread
      |11:24:03.254| [0] [Reactor::breakLoop] reactor stopped
      

      I don't use QTimer anywhere in my code, so I suppose this is a timer somewhere in the Qt framework itself.

      I have also tried destroying the QApplication from main thread, but that causes a segmentation fault.

      Questions:

      • What exactly is causing this error?
      • Is running Qt applications on a thread other than main-thread viable?
      • How can I tear down QApplication etc safely, without having these kinds of errors?
      kshegunovK Offline
      kshegunovK Offline
      kshegunov
      Moderators
      wrote on last edited by kshegunov
      #2

      @skebanga said in Running gui in thread other than main thread - QObject error: Timers cannot be stopped from another thread:

      What exactly is causing this error?

      My best guess would be that you have created a QObject before the application object. But more code would be needed to confirm or deny that.

      Is running Qt applications on a thread other than main-thread viable?

      Yes. See here

      How can I tear down QApplication etc safely, without having these kinds of errors?

      By making it the first QObject to come into existence and the last one to go into oblivion. Plus I advise using the stack for that instead of doing dynamic allocations.

      Read and abide by the Qt Code of Conduct

      S 1 Reply Last reply
      2
      • kshegunovK kshegunov

        @skebanga said in Running gui in thread other than main thread - QObject error: Timers cannot be stopped from another thread:

        What exactly is causing this error?

        My best guess would be that you have created a QObject before the application object. But more code would be needed to confirm or deny that.

        Is running Qt applications on a thread other than main-thread viable?

        Yes. See here

        How can I tear down QApplication etc safely, without having these kinds of errors?

        By making it the first QObject to come into existence and the last one to go into oblivion. Plus I advise using the stack for that instead of doing dynamic allocations.

        S Offline
        S Offline
        skebanga
        wrote on last edited by
        #3

        @kshegunov Hmmm, you are correct - I have some objects being created at static init time.

        Thanks for the reply!

        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