qttabsqmlqt5.9

"Object is not defined" in TabView


Trying to get this to work in Qt version 5.9

It seems that whenever I create an object within a QML Tab it is unrecognizable by the parent object (or any of the parent's parents, and so on). How do I get the parent objects to recognize the object in the Tab? Or, if impossible, then what is a work-around to call the function of the object within the Tab?

I've boiled down the code to this simplified example:

import QtQuick 2.9
import QtQuick.Window 2.2
import QtQuick.Controls 1.4

Window {
    Rectangle {
        id: myFunctionCaller

        Component.onCompleted: {
            myParent.myFunction();
            myChild.myFunction();
            myGrandChild.myFunction();
        }
    }

    TabView {
        id: myParent
        property Rectangle grandchild: myGrandChild
        onGrandchildChanged: console.log("Parent recognizes GrandChild");

        function myFunction() {
            console.log("I'm the Parent");
        }

        Tab{
            id: myChild
            property Rectangle grandchild: myGrandChild
            onGrandchildChanged: console.log("Child recognizes GrandChild");

            function myFunction() {
                console.log("I'm the Child");
            }

            Rectangle {
                id: myGrandChild
                function myFunction() {
                    console.log("I'm the GrandChild");
                }
            }
        }
    }
}

I expect this output:

I'm the Parent
I'm the Child
I'm the GrandChild
Parent recognizes Grandchild
Child recognizes Grandchild

However, I get this output:

I'm the Parent
I'm the Child
ReferenceError: myGrandChild is not defined.
ReferenceError: myGrandChild is not defined.
ReferenceError: myGrandChild is not defined.

The error occurs on these lines:

myGrandChild.myFunction();
onGrandchildChanged: console.log("Parent recognizes GrandChild");
onGrandchildChanged: console.log("Child recognizes GrandChild");

Solution

  • The Tab is a subclass of Loader, so the Rectangle is not created until the Tab becomes active.

    Tabs are lazily loaded; only tabs that have been made current (for example, by clicking on them) will have valid content. You can force loading of tabs by setting the active property to true

    Thus the id: myGrandChild is only available within the (source)Component automatically created in the Loader.

    The solution is, to activate the Tab and address the child with myChild.item

    (Not tested)