Required Properties(必备属性)
有时,您的组件需要设置一些属性,但没有合适的默认值。例如,您可能关心按钮的易访问性(Accessibility),因此当您创建了一个AccessibleButton控件,它至少应该有一个description属性。
但是,按钮具有description属性这一事实并不意味着任何人都会设置它。所以您或您的同事可能会在某个时候用以下代码实例化组件:
关于易访问性就讲到这里:现在description属性只是一个空字符串!当然,您可以为属性设置一个默认值,但是用哪个呢?“Button”基本没用。"您不应该听到这个"?好吧,至少QA现在可能会针对它。但是,如果QML引擎知道需要设置此属性,不是更有用吗?
不幸的是,在Qt 5.15之前没有办法强制设置description属性。但从Qt 5.15开始,这就成为可能:
现在,如果创建一个AccessibleButton,但没有设置description属性,那么整个应用程序将无法启动。但如果该组件是动态创建的(例如通过Loader加载),则无法做到这一点。这种情况下,将仅出现运行时警告。
我们还计划为qmllint和QtCreator添加更多的工具支持,以便在未设置Required Properties时显示警告。
Required Properties和Delegates
此外,Required Properties在Delegates中扮演着特殊的角色。正如您可能知道的,Delegates可以通过名称以及其他属性,如model和index,直接访问所提供的模型角色。
如果您的Delegates不包含Required Properties,则此处不会发生任何更改。但是,如果它们包含至少一个Required Properties,那么这些名称就不能再访问了。相反,您必须将它们显式的指定为Required Properties。
然后QML引擎将相应设置Required Properties。请注意,如您的model是可编辑的,新方法和旧方法之间有一个重要的区别:使用旧方法,您可以这样写代码:
model也会相应更新。但如果你这样写代码
然后,description的绑定将被破坏(QML引擎将会打印警告),model将不会被更新。我们决定采用这种行为,以确保无论在delegates中或在delegates之外使用,components的行为不会有太大的差异。此外,我们也不鼓励任何人对属性执行命令式赋值(因为这通常会破坏绑定)。
如果您确实想要更新model的值,当然还有一种办法可以实现:将model设置为Required Properties并用以下代码
我们建议您始终在Delegates中使用Required Properties。这避免了非限定查找,后者对工具来说是个问题,并往往会降低处理速度。
Inline Components(内联组件)
Qt 5.15中的另一个新特性是内联组件。顾名思义,它们允许您在文件中定义一个新组件。基本语法是
在文件内部,您可以通过名称引用新组件,就像在其自己的文件中定义的一样。让我们以LabeledImage组件为例来说明其工作原理:
您也可以在其它文件中引用该组件。在这种情况下,您需要在其名字之前加上包含其组件的名称:
您可能会想,既然QML已经有了组件类型,为什么还要使用内联组件呢?查看前面的示例,我们可以看到,内联组件使您可以执行组件无法执行的以下操作:
您可以在没有Loader开销的情况下创建组件实例。
您可以在属性声明中使用组件类型。
您可以在定义组件的文件之外的其他文件中引用该组件。
希望您能和我们一样方便地找到内联组件!
Nullish Coalescing(空值合并)
最后一个新语言特性是由我们的实习生Maximilian Goldstein实现的。虽然QML通常只支持EcmaScript 6,但是Maximilian为一个即将提出的语言特性增加了支持,该特性正在被添加到最新的EcmaScript标准中:空值合并。引用MDN:
空值合并操作符(??)是一个逻辑操作符,当其左侧操作数为空或未定义时,返回其右侧操作数,否则返回其左侧操作数。
有关详细信息,请参阅MDN页面。下面是一个示例,演示如何在QML中使用它来设置JSON中的属性,并在未提供属性的情况下提供合理的默认值。
注意我们在设置brightness时不能用“||”代替“??”。因为settings.brightness可能已经是0,在这种情况下,我们将获取默认值。