如何避免 QML 中的重复代码?

How to avoid repetitive code in QML?

我正在使用 Qt 5.4.1。

我目前正在 QML 中设置一些按钮。我希望某些按钮具有类似的状态行为 - 如何避免通过 QML 重复大量非常相似的代码?

Rectangle {
        id: songFilterButton

        x: 0; width: 80
        y: 0; height: 60

        Text {
            anchors.centerIn: parent
            text: "Songs"
        }

        state: "on"; states: [
            State {
                name: "on"
                PropertyChanges{ target: songFilterButton; color: "steelblue" }
            },
            State {
                name: "on"
                PropertyChanges{ target: songFilterButton; color: "white" }
            }
        ]

        MouseArea { id: region; anchors.fill: parent; onClicked: songFilterButton.toggle() }

        function toggle() {
            if(state == "on") { state = "off" } else { state = "on" }
        }
    }

如果要为多个按钮重复这样的代码,那将是相当多的代码,而且每次我向按钮添加功能(例如向 C++ 发送信号和其他行为)时,我都必须多次执行此操作...

我阅读了 MrEricSir 提供的 link 并使用以下代码创建了一个 HKRadioButton.qml:

import QtQuick 2.0

Rectangle {
    property string text: label.text

    Text {
        id: label
        anchors.centerIn: parent
    }

    state: "on"; states: [
        State {
            name: "on"
            PropertyChanges{ target: songFilterButton; color: "steelblue" }
        },
        State {
            name: "off"
            PropertyChanges{ target: songFilterButton; color: "white" }
        }
    ]

    MouseArea { anchors.fill: parent; onClicked: parent.toggle() }

    function toggle() {
        if(state == "on") { state = "off" } else { state = "on" }
    }
}

在我的主要 QML 文件中,我有

HKRadioButton {
        id: songFilterButton

        x: 0; width: 80
        y: 0; height: 60

        text: "Songs"
    }

我得到行为(改变状态),但不是文本...

改变

property string text: label.text

property alias text: label.text

现在你只需将 label.text 分配给拥有 属性 HKRadioButton.text 但它应该只是相反的操作。

定义您自己的组件。您可以创建一个组件 "in place",然后右键单击该组件的根对象 -> 重构 -> 将组件移动到单独的文件中。例如:

Rectangle {
    id: button
    ...
}

将其移动到 Button.qml 后,您可以使用:

Button {
    ...
}

使用"inline"个组件:

Component {
    id: button
    Rectangle {
        ...
    }
}

然后您可以将 buttonLoader 一起使用,或者使用 button.createObject(parentItem)

进行动态实例化

正如另一个答案所指出的,如果您想为引用某些子对象属性的组件创建属性,请使用别名 属性,有助于避免不必要的绑定。

Rectangle {
    property string text

    Text {
        id: label
        anchors.centerIn: parent
        text: parent.text // this is what you want
    }
    ...
}

但这会引入不必要的绑定,您可以使用 alias 从根组件 属性 直接引用标签的 text,如 folibis 建议的那样。