在 QML 中设置子项属性的正确方法

Posted

技术标签:

【中文标题】在 QML 中设置子项属性的正确方法【英文标题】:Proper way to set a child item property in QML 【发布时间】:2021-10-13 14:02:09 【问题描述】:

每个人都知道如何通过这些元素的背景属性为按钮、弹出窗口等设置背景。但我想知道,我怎样才能自己为自己的自定义元素创建这样的属性?我找到了一种方法,但它看起来很丑陋,我似乎找不到定义所述属性的 Button、Popup 等的 qml 代码。所以我玩了一下,想出了这样使用 Bindings 的想法:

Item 
    id: root
    property Item background: Rectangle 
        color: "red"
    
    Binding 
        target: root.background
        property: "parent"
        value: root
    
    Binding 
        target: root.background
        property: "anchors.fill"
        value: root
        when: root.background.parent == root
        delayed: true
    

如前所述,如果您需要声明孩子的许多属性,这看起来很烦人。那么,Qt 是如何做到的,或者正确的做法是什么?

【问题讨论】:

如果您要查找 Button 的 background 属性的定义位置,它位于 C++ 代码中。 Button 派生自 AbstractButton,AbstractButton 派生自 Control。您可以找到声明为here 的控件的background 属性。 我实际上是在寻找 qml 声明,如果这样的事情存在,因为我对 qml 的执行方式感兴趣。不过还是谢谢你! 正如我所说,在 QQC2 源代码中,该属性是用 C++ 定义的,而不是 qml。 【参考方案1】:
// ItemWithBackground.qml
Item 
    property alias background: backgroundLoader.sourceComponent

    Loader 
        id: backgroundLoader
        anchors  fill: parent 
        sourceComponent: Rectangle  color: 'red'  // default background implementation 
    


// Usage example:
ItemWithBackground 
    background: Rectangle 
        color: 'green'
    

【讨论】:

没想到会这样使用Loader。但这是有道理的。谢谢! @Tanzmaus 请注意,在 Qt Quick Controls 2 中所做的 QML 方式确实是您在问题中实际发布的内容。但是,必须定义多个 Binding 对象并不是很实际。 QQC2 在 C++ 中完成。使用这里提到的加载器会改变语义,绿色的矩形现在是一个组件,而不是一个项目的实例。例如,如果你为它指定一个 id,你就不能在它的范围之外访问。而且您也无法将背景作为项目访问。 myRect.color = "orange" 不起作用,background.visible = false 也一样。它还创建了一个QQuickItem【参考方案2】:

如果您使用的是最新的 Qt 版本,请查看使用内联组件。它们允许您轻松创建这样的 API。

【讨论】:

以上是关于在 QML 中设置子项属性的正确方法的主要内容,如果未能解决你的问题,请参考以下文章

如何在 QML 中设置 MessageDialog 的默认按钮?

QML 对象不更新显示

在数组中设置选择列表值的正确方法?

我正在尝试获取对我的 Firebase 数据库子项的正确引用并在我的 RecyclerView 中设置值,但我遇到了一些问题

如何在 QML 中设置鼠标光标位置

如何在 UITextField 子类中设置 UITextField 的属性