QML:在派生类中使属性只读

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了QML:在派生类中使属性只读相关的知识,希望对你有一定的参考价值。

我很确定答案是否定的,但我认为无论如何我都应该问。可以在纯QML派生类中将继承属性设置为只读/常量吗?

// Base.qml
Item {
    property int foo: 42
}

// Derived.qml
Base {
    foo: 99 // Make constant somehow!
}

我正在通过检测foo的变化并将错误打印到控制台来解决这个问题,但这不是好API的标志......

我有一个菜单项类,可以表示菜单项,子菜单,分隔符等。我需要专门化它的行为,但仅限于它处于子菜单模式时。我可以更改继承树,因此每个菜单类型都有一个子类,但这似乎很愚蠢,因为每个子类只包含一个readonly属性。但是,如果没有其他办法,我将不得不这样做。

答案

为什么不使用继承的getter / setter作为私有foo?就像是 :

//Base.qml
Item
{
    QtObject
    {
       id : privateFoo
       property int foo : 42
    }

    function getFoo() {return privateFoo.foo;}
    function setFoo(newFoo) { privateFoo.foo = newFoo; }
}

//derived.qml
Base
{
    function getFoo() {return 99;}
    function setFoo(newFoo) { /*do nothing */ }
}

(我还没有测试过这段代码)

另一答案

您还可以将foo转换为readonly alias,将其转换为内部属性_foo,仅用于派生类中的赋值:

// Base.qml
Item {
    id: base

    readonly property alias foo: base._foo

    property int _foo: 42 // only used for assignment in subclasses
}

要在另一个组件中使用:

Item {
    Base {
        id: child0
    }

    Base {
        id: child1
        _foo: 99
    }

    Base {
        id: child2
        _foo: child1.foo
    }

    Component.onCompleted: {
        console.log("child0:", child0.foo,"child1:", child1.foo, "child2:", child2.foo)
        child1.foo = 5 // not allowed!
        console.log("child0:", child0.foo,"child1:", child1.foo, "child2:", child2.foo)
    }
}

输出:

child0: 42 child1: 99 child2: 99
TypeError: Cannot assign to read-only property "foo"

注意:当然以后仍然可以修改_foo。但是如果你记得只将它用于赋值,那么你就可以在派生类中使用readonly foo

以上是关于QML:在派生类中使属性只读的主要内容,如果未能解决你的问题,请参考以下文章

在派生类中将属性设为只读

Qml中的“无效的属性分配:..只读属性”

降低基类属性的可见性

26.Qt Quick QML-RotationAnimationPathAnimationSmoothedAnimationBehaviorPauseAnimationSequential(代码片段

在使用基类中的方法时使用派生类中的属性?

如何在Rails中使数据库字段为只读?