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

QApplication in non-main thread



  • Hi!

    I'm trying to write a lib based on Qt that'd have QApplication running in a separate thread. The idea is to have these exported functions (to be called from "user's" thread):

    • Init(), that'd create the new thread (in which QApplication is created, ::exec() is called and QApplication is deleted after ::exec() returned),
    • Exit(), that would emit a signal connected to QApplication's quit slot, and then join the created thread.
    • Other functions that would only be called in between the above two, create some QObjects and interact with the QApplication instance. All the created QObjects will be deleted before QApplication::exec() returns.

    Unfortunately I have to use a rather old Qt version (5.5.0), in which I experience some clean-up issues.
    The problem is that there are still some QObjects alive after Exit() returned - I see that by setting a breakpoint at QObjectPrivate::~QObjectPrivate() which gets triggered several times when my main returns. Another problem is that if some secondary event loops were created in between Init() and Exit() calls, I also get this warning when main returns:

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

    Here's a code that reproduces the problem for me (based on Why the main thread is needed for QCoreApplication?):

    #include <QApplication>
    #include <QTimer>
    #include <QMessageBox>
    #include <thread>
    void func()
    {
        QMessageBox::information(nullptr, "Info", "Hello!");
    }
    void runsInOtherThread(int argc, char *argv[])
    {
        QApplication a(argc, argv);
        a.setQuitOnLastWindowClosed(false);
        QTimer::singleShot(100, &a, &func);
        QTimer::singleShot(3000, &a, &QCoreApplication::quit); //spin for 3 seconds 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;
    }
    

    If I comment out the QMessageBox part, I don't get the warning but still see some QObjects destroyed at main's exit. On Qt 5.10 it works fine though (no QObjectPrivate::~QObjectPrivate() calls after the thread was joined).

    Can there be some manual clean-up used for 5.5 to avoid this issue? Or maybe some simple patch to Qt?