Qml root deleted on startup



  • Issue:

    I have a qt 4.8.4 application that sets the source for my declarative view, all the components complete (Component.onCompleted called) but then Component.onDestruction is called straight away. The qml loaded is the UI for a fairly substantial application(about 250 qml files).

    The root element is getting a deleteLater event but I cant see where from or why
    The declarative view does not get a close event
    There are no warnings printed during startup.
    If I add more qml menus the problem goes away but makes me wonder if I have a ticking time bomb.
    If I port the app to qt5 for testing it does not destroy everything on startup

    Questions:
    why would the root be destroyed, what can I look for?
    is working around the issue going to cause pain later?



  • Usually there'll be a signal handler or something which is invoked prior to the point that object creation completes (or more correctly, prior to the point where all of the first-time-binding-evaluations for the object, have completed). During that time, there is a window where an object can be marked for destruction via an explicit .destroy(), or due to garbage collection if an object isn't referenced in a JS var and you call gc() manually or the JS engine decides it needs to clean stuff up.

    In Qt5, significant effort was expended to stop this from occurring (which is why the QQmlData - better name QQmlObjectPrivate - class gained a bunch of flags like isRootObjectInComponent / isQueuedForDeletion / etc etc), and so you shouldn't have this problem in Qt5. In Qt4, a simple work around (if it is indeed a gc issue) is to have a .pragma library js resource imported by your root component, which contains:

    @
    // stopgc.js
    .pragma library

    var stopRootObjectGc = null
    function storeReference(obj) { stopRootObjectGc = obj }
    @

    Then in your QML have something like:

    @
    import "stopgc.js" as StopGC

    Item {
    id: root
    Component.onCompleted: { StopGC.storeReference(root) }
    }
    @

    If, on the otherhand, you are somehow manually deleteLater()ing the object, or destroy()ing it, then this will not help.

    Cheers,
    Chris.



  • Sounded good but still get destroyed :(



  • Put some debugging in the dtor of your custom object. Get a backtrace. Most likely you'll see it being deleted via processEvents() due to a deleteLater(). Are you 100% certain that you don't have a manual destroy() in your code anywhere? You're certain that you're not accidentally deleting the view, the engine, or the context?

    Without more information, I can't really suggest any other ways to work around the issue, but it sounds like something is manually deleting your root object... If it still gets deleted even with a pragma library var holding a reference to it, then I can almost guarantee that the root object isn't being deleted by the garbage collector, and so that doesn't leave many other possibilities.

    Cheers,
    Chris.



  • Yes it is due to a deleteLater, I do not have a manual destroy, adding duplicates of some menus to the qml tree stops the problem but that has a bad smell.



  • I am having this same problem. I created the following bug: https://bugreports.qt-project.org/browse/QTBUG-31678


Log in to reply
 

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