1

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");
eyllanesc
  • 235,170
  • 19
  • 170
  • 241
Tyler M
  • 352
  • 4
  • 21

1 Answers1

1

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)

  • So can I assume that the myGrandChild tab is active by default, since it is the only tab in the myChild TabView? If this is the case, then I should be able to call mChild.item.myFunction() correct? I tried this and it hasn't made a difference, I still get "myGrandChild is not defined" – Tyler M May 28 '19 at 16:07
  • If you really call `myChild.item.myFunction()` you do not reference myGrandChild. This error has to occure from one of your lines, where you try to reference the `Rectangle` through the `id: myGrandChild` - which is out of scope for all objects but the `Rectangle` itself. – derM - not here for BOT dreams May 28 '19 at 16:12
  • `myGrandChild.myFunction();` -> `myChild.item.myFunction()`, in `TabView`: `property Rectangle grandchild: myGrandChild` -> `property Rectangle grandchild: myChild.item`, in `Tab`: `property Rectangle grandchild: myGrandChild` -> `property Rectangle grandchild: item` – derM - not here for BOT dreams May 28 '19 at 16:19
  • You're absolutely right, there was a typo on my end. Thanks! – Tyler M May 28 '19 at 16:22
  • Allow me to pose one more question for you: If I visually am looking at Tab1, and something I click should call a function housed in Tab2, even though Tab1 is the active tab (and Tab2 is not) is it still possible to call a Tab2 function? Or is this a bad general practice? – Tyler M May 28 '19 at 16:29
  • I would argue, it would be better to seperate the data on which you might act (model) from the tab (view) and call the function on the model, that will change the displayed data in tab2 once this becomes active. As such you are able to turn the tabs inactive without loss of data. – derM - not here for BOT dreams May 28 '19 at 16:36