2015-02-27 2 views
2

Я уверен, что ответ отрицательный, но я думал, что должен все равно спросить. Может ли унаследованное свойство быть сделанным readonly/constant в чистом классе QML?QML: Сделать свойство readonly в производном классе

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

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

Я в настоящее время решения этого путем обнаружения изменения foo и печатая ошибку в консоли, но это вряд ли признак хорошего API ...

У меня есть класс пункт меню, который может представляют записи меню, подменю, разделители и т. д. Мне нужно специализироваться на его поведении, но только, когда он находится в режиме подменю. Я могу изменить дерево наследования, поэтому у меня есть подкласс для каждого типа меню, но это кажется глупым, поскольку каждый подкласс будет содержать только одно свойство readonly. Однако, если нет другого пути, мне придется.

+0

Что вы хотите сделать? Для чего вам это нужно? Может быть, есть еще одно решение для этого. – folibis

+0

@folibis Я обновил свой вопрос. – cmannett85

ответ

2

Почему бы не использовать унаследованные getter/seters для частного 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 */ } 
} 

(я не проверял этот код)

+0

Это работает хорошо, моя единственная забота заключается в том, что он не решает проблему с помощью «QML-парадигмы», то есть посредством манипулирования свойствами. Сказав, что привязка свойств все еще работает так, как ожидалось, поэтому я не могу слишком спорить. – cmannett85

+0

Да, это позор, соглашение о частных свойствах - это префикс своего имени на '__', например. '__foo' здесь, но это не мешает кому-либо изменять это свойство. Это просто указание, что это свойство должно быть только внутренним. – GrecKo

0

Вы также можете преобразовать 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 в производном классе.