How to avoid repetitive code in QML?

99封情书 提交于 2019-12-25 03:44:13

问题


I'm using Qt 5.4.1.

I'm currently setting up some buttons in QML. I want similar state behaviours for some of the buttons - how to do I avoid having large chunks of very similar code repeated through the 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" }
        }
    }

That would be quite a bit of code to repeat for several buttons, and each time I add to a button functionality (like sending signals to C++ and other behaviours), I would have to do it multiple times...

I've read over the link provided by MrEricSir and created a HKRadioButton.qml with the following code:

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" }
    }
}

In my main QML file, I have

HKRadioButton {
        id: songFilterButton

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

        text: "Songs"
    }

I get the behaviour (changing state), but not the text...


回答1:


Define your own components. You can create a component "in place" and then right-click on the component's root object -> Refactoring -> Move component into separate file. For example:

Rectangle {
    id: button
    ...
}

After you move that to a Button.qml, you can just use:

Button {
    ...
}

Use "inline" components:

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

Then you can use button with a Loader or for dynamic instantiation using button.createObject(parentItem)

As the other answer noted, if you want to create properties for your component which refer to some sub-object properties, use an alias property, helps avoid unnecessary bindings.

Rectangle {
    property string text

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

But that would introduce a needless binding, you can use an alias to directly reference the label's text from the root component property as folibis suggested.




回答2:


Change

property string text: label.text

to

property alias text: label.text

Now you just assign label.text to own property HKRadioButton.text but it should be just the opposite action.



来源:https://stackoverflow.com/questions/28909050/how-to-avoid-repetitive-code-in-qml

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!