Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

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



  • 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?

  • Qt Champions 2017

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



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

    Thanks for the reply!


Log in to reply