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

Object destroyed while one of its QML signal handlers is in progress



  • Hello,
    for quite a while now I am facing an issue with my QML application, running on Qt 5.13.1 under Windows 10.
    The situation is the following, I have a listview with a bunch of delegates, depending on which delegate I click a different .qml file is loaded into an adjacent loader.
    Inside this .qml file a QQuickPaintedItem derived QML plugin resides, which takes a couple seconds to load.
    Everything works as expected as long as I do not start clicking on two different delegates too rapidly.

    Once I start doing that, it is a matter of time until I encounter the following error:

    Object 0x2f4cdd60 destroyed while one of its QML signal handlers is in progress.
    Most likely the object was deleted synchronously (use QObject::deleteLater() instead), or the application is running a nested event loop.
    This behavior is NOT supported!
    qrc:/pages/foo.qml:38: function() { [native code] }
    

    Line 38 of foo.qml

    Component.onCompleted: {
                   console.log(this)
                   bar("hello")
               }
    

    I inserted the console output to confirm that the error is actually caused by this object and my assumption turned out to be true.
    As this error is pretty much non-specific I did some more research in codebase and I noticed that another piece of code that the post-mortem debugger often digs up is related to a QNetworkAccessManager that somebody made synchronous:

    void SynchronousNetworkAccessManager::makeSynchronousRequest(const QNetworkReply *reply) const    
        {    
            QEventLoop loop;    
            connect(reply, SIGNAL(finished()), &loop, SLOT(quit()));    
            loop.exec();
             
            if (reply->error() != QNetworkReply::NoError)    
            {    
                 qDebug() << reply->errorString();    
            }    
        }
    

    This function is called by a function of this type:

    QNetworkReply *SynchronousNetworkAccessManager::post(const QNetworkRequest &request, const QByteArray &data) const
    {
        qDebug() << "POST" << request.url() << data;
        QNetworkReply *reply = networkAccessManager->post(request, data);
        makeSynchronousRequest(reply);
        qDebug() << "POST-RETURNED" << request.url() << data;
        return reply;
    }
    

    I added the debug output to confirm that the request would finish and just as the application crashes a request is sent previously which does not occur. However, after a couple of google searches I was unable to confirm that this is the culprit, although it is a nested event loop as mentioned in the error (I guess at least), but on the other hand my knowledge of these is very limited.

    The line that shows up in the post-mortem debugger is in qqmlprivate.h:108 in QQmlPrivate::QQmlElement<MyPlugin>::~QQmlElement<MyPlugin>

            ~QQmlElement() override {
                QQmlPrivate::qdeclarativeelement_destructor(this);
            }
    

    I can pretty much guess what is happening, however I have no clue how to prevent it... So my questions are basically:

    • How can I effectively debug this kind of error?
      What can I do to prevent it, the error message does not help me a lot.

    Thank you!


Log in to reply