Компоненты QML

Добавлено 1 марта 2022 в 18:31

Компонент – это повторно используемый элемент. QML предоставляет различные способы создания компонентов. Сейчас мы рассмотрим только самую простую форму – компонент на базе файла. Компонент на базе файла создается путем помещения элемента QML в файл и присвоения этому файлу имени элемента (например, Button.qml). Вы можете использовать этот компонент, как и любой другой элемент из модуля Qt Quick. В нашем случае вы использовали бы его в своем коде как Button {...}.

Например, давайте создадим прямоугольник, содержащий текстовый компонент и область обработки событий мыши. Это похоже на простую кнопку и для наших целей не должно быть более сложным.

Rectangle { // наш интерфейс встроенной кнопки
    id: button
    x: 12; y: 12
    width: 116; height: 26
    color: "lightsteelblue"
    border.color: "slategrey"
    Text {
        anchors.centerIn: parent
        text: "Start"
    }
    MouseArea {
        anchors.fill: parent
        onClicked: {
            status.text = "Button clicked!"
        }
    }
}

Text { // текст меняется при нажатии на кнопку
    id: status
    x: 12; y: 76
    width: 116; height: 26
    text: "waiting ..."
    horizontalAlignment: Text.AlignHCenter
}

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

пример кнопки
пример кнопки

Теперь наша задача – извлечь пользовательский интерфейс кнопки в повторно используемый компонент. Для этого мы должны подумать о возможном API для нашей кнопки. Вы можете сделать это, представив, как кто-то другой должен использовать вашу кнопку. Вот что я придумал:

// минимальный API для кнопки
Button {
    text: "Click Me"
    onClicked: { /* сделать что-нибудь */ }
}

Я хотел бы установить текст с помощью свойства text и реализовать свой собственный обработчик кликов. Кроме того, я ожидаю, что кнопка будет иметь разумный начальный размер, который я могу перезаписать (например, width: 240).

Для этого мы создаем файл Button.qml и копируем внутрь наш пользовательский интерфейс кнопки. Кроме того, нам нужно экспортировать свойства, которые пользователь может захотеть изменить на корневом уровне.

// Button.qml

import QtQuick

Rectangle {
    id: root
    // экспорт свойств кнопки
    property alias text: label.text
    signal clicked

    width: 116; height: 26
    color: "lightsteelblue"
    border.color: "slategrey"

    Text {
        id: label
        anchors.centerIn: parent
        text: "Start"
    }
    MouseArea {
        anchors.fill: parent
        onClicked: {
            root.clicked()
        }
    }
}

Мы экспортировали свойство text и сигнал clicked на корневой уровень. Обычно мы называем наш корневой элемент root, чтобы упростить обращение к нему. Мы используем функционал псевдонимов QML, который позволяет экспортировать свойства внутри вложенных элементов QML на корневой уровень и сделать их доступными для внешнего мира. Важно знать, что извне этого файла другие компоненты могут получить доступ только к свойствам корневого уровня.

Чтобы использовать наш новый элемент Button, мы можем просто объявить его в нашем файле. Таким образом, предыдущий пример станет немного проще.

Button { // наш компонент Button
    id: button
    x: 12; y: 12
    text: "Start"
    onClicked: {
        status.text = "Button clicked!"
    }
}

Text { // текст меняется при нажатии на кнопку
    id: status
    x: 12; y: 76
    width: 116; height: 26
    text: "waiting ..."
    horizontalAlignment: Text.AlignHCenter
}

Теперь вы можете использовать в своем пользовательском интерфейсе столько кнопок, сколько захотите, просто используя Button { ... }. Настоящая кнопка может быть более сложной, например, обеспечивать обратную связь при нажатии или показывать более красивое оформление.

Совет

Если вы хотите, то можете пойти еще дальше и использовать Item в качестве корневого элемента. Это не позволит пользователям изменять цвет кнопки, которую мы разработали, и дает нам больший контроль над экспортируемым API. Цель должна состоять в том, чтобы экспортировать минимальный API. На практике это означает, что нам нужно заменить корневой Rectangle на Item и сделать прямоугольник вложенным элементом в корневой элемент.

Item {
    id: root
    width: 116; height: 26

    property alias text: label.text
    signal clicked

    Rectangle {
        anchors.fill parent
        color: "lightsteelblue"
        border.color: "slategrey"
    }
    ...
}

С помощью этой технологии можно легко создать целый ряд компонентов, доступных для повторного использования.

Теги

GUI / Графический интерфейс пользователяQMLQtQtQuickОбучениеПрограммирование

На сайте работает сервис комментирования DISQUS, который позволяет вам оставлять комментарии на множестве сайтов, имея лишь один аккаунт на Disqus.com.

В случае комментирования в качестве гостя (без регистрации на disqus.com) для публикации комментария требуется время на премодерацию.