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 2016

    @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
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.