Private properties in QML



  • It seems like all instanciated objects in QML inherits all properties from the object it has been instanciated from.
    What if you want a property in a parent that should not be accessible from a child?
    If your creating a library for example that you don't want to be able to access everything from your main application?

    I've tried using this example to make properties private but it doesen't work, was it only prior to qt 5 it worked?
    https://qt.gitorious.org/qt-components/pages/CodingStyle
    @
    ////main.qml

    Rectangle {

    Item {
    QtObject {
    id: internal
    property int shouldBeInvisibleOutsideThisQmlFile: 1
    }
    }

    Test {

    }

    }

    ////Test.qml

    Rectangle {

    width: internal.shouldBeInvisibleOutsideThisQmlFile; //this works but shouldn't

    }
    @



  • This works the other way around. Parents can't access properties of children that aren't in the top level item. Children can access properties of parents.



  • Yes I know but shouldn't it be possible to make a property not accessable from child items?

    Lets say you want a property called dataContext on each view in QML if you have a childview that also have a property dataContext this will point to the partent dataContext property. It should be convenient to somehow be able to make a property private and only visible from one QML-file.



  • I'm not sure what the view being referred to is. Is this an observed or a speculative problem?

    A property in a child will hide property with the same name in the parent.

    main.qml
    @
    import QtQuick 2.2

    Rectangle {
    width: 360
    height: 360

    property string myProperty: "parent"
    
    MouseArea {
        anchors.fill: parent
        onClicked: console.log("parent: " + myProperty)
    }
    
    Child {}
    

    }

    @

    Child.qml
    @import QtQuick 2.0

    Rectangle {
    width: 100
    height: 100

    color: "red"
    property string myProperty: "Child"
    MouseArea {
        anchors.fill: parent
        onClicked: console.log("Child: " + myProperty)
    }
    
    Rectangle {
        property string myProperty: "sub-Child"
        width: 50
        height: 50
        color: "green"
        MouseArea {
            anchors.fill: parent
            onClicked: console.log("sub-Child: " + myProperty)
        }
    }
    

    }
    @



  • Thx for the feedback.

    I have a tabview with different QML-pages in each tab.
    Its possible to workaround but lets say you want to set a property in a child that has the same name as a property in the parent,
    that wont work.

    @//Main.qml (parent)
    import QtQuick 2.2

    Rectangle {
    width: 360
    height: 360

    property CppClass1 dataContext: CppClass1{}
    
    Child {
       dataContext: dataContext.childDataContext //This won't work because dataContext is always refering to the one in this qml file. Any ideas except changing the name of dataContext?
    }
    

    }

    //Child.qml
    import QtQuick 2.0

    Rectangle {
    width: 100
    height: 100

    property CppClass2 dataContext: CppClass2{}

    }@



  • How about giving the Child{} an id, and then using that to refer to the child's dataContext property? The same idea can be applied to accessing the parent, or by use of an explicit parent.

    ie (compressed for brevity):

    @
    Rectangle {
    id: parentItem
    property variant myProperty

    Child {
        id: childItem
        property variant myProperty 
        // use parentItem.myProperty or parent.myProperty
        //if the parent is the intended source
        property variant targetProperty: childItem.myProperty
    }
    

    }
    @

    Changing the name of a property for the sake of clarity isn't a bad option, when the development process allows for it.



  • thx for the tip

    dataContext: dataContext.childDataContext
    this line was actually referering to the dataContext in the child.qml file all the time. I changed it to this and now it works :)

    @//Main.qml (parent)
    import QtQuick 2.2

    Rectangle {
    id: mainPage
    width: 360
    height: 360

    property CppClass1 dataContext: CppClass1{}
    
    Child {
       dataContext: mainPage.dataContext.childDataContext 
    }
    

    }

    //Child.qml
    import QtQuick 2.0

    Rectangle {
    width: 100
    height: 100

    property CppClass2 dataContext: CppClass2{}

    }@



  • However "mainPage.dataContext.childDataContext" can then be called from the rest of the appliaction. Not a big issue but would be nice to make the parent dataContext private (only available in main.qml) somehow.



  • I agree that enforcing a cleaner interface would be nice. As is, property use takes a little more discipline


Log in to reply
 

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