Как избежать повторяющегося кода в 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, и создал 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"
    }

Я получаю поведение (изменение состояния), но не текст...


person HorusKol    schedule 06.03.2015    source источник
comment
Вы просто определяете новые типы QML, помещая их в отдельные файлы. Дополнительная информация находится здесь, в документации: doc.qt.io/qt- 5/qtqml-documents-topic.html   -  person MrEricSir    schedule 07.03.2015


Ответы (2)


Определите свои собственные компоненты. Вы можете создать компонент «на месте», а затем щелкнуть правой кнопкой мыши корневой объект компонента -> Рефакторинг -> Переместить компонент в отдельный файл. Например:

Rectangle {
    id: button
    ...
}

После того, как вы переместите это в Button.qml, вы можете просто использовать:

Button {
    ...
}

Используйте встроенные компоненты:

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

Затем вы можете использовать button с Loader или для динамического создания экземпляров с помощью button.createObject(parentItem)

Как отмечалось в другом ответе, если вы хотите создать свойства для своего компонента, которые ссылаются на некоторые свойства подобъекта, используйте свойство псевдонима, что помогает избежать ненужных привязок.

Rectangle {
    property string text

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

Но это приведет к ненужной привязке, вы можете использовать alias для прямой ссылки на text метки из свойства корневого компонента, как предлагает фолибис.

person dtech    schedule 07.03.2015

Изменять

property string text: label.text

to

property alias text: label.text

Теперь вы просто назначаете label.text собственному свойству HKRadioButton.text, но это должно быть прямо противоположное действие.

person folibis    schedule 07.03.2015