Spec-Zone.ru › Qt 5.15

Определение типов объектов через QML-документы

Одна из ключевых особенностей QML заключается в том, что она позволяет легко определять типы QML-объектов в лёгком формате с помощью QML-документов, адаптируя их под нужды отдельных QML-приложений. Стандартный модуль Qt Quick предоставляет различные типы, такие как Прямоугольник, Текст и Изображение для создания QML-приложения; помимо этого, вы можете легко определять собственные QML-типы для повторного использования в вашем приложении. Эта возможность создания собственных типов является основой любого QML-приложения.

Определение типа объекта с помощью QML-файла

Именование пользовательских QML-типов объектов

Для создания типа объекта QML-документ должен быть помещен в текстовый файл с именем <TypeName>.qml, где <TypeName> — желаемое имя типа. Имя типа должно соответствовать следующим требованиям:

  • Он должен состоять из буквенно-цифровых символов или символов подчеркивания.
  • Он должен начинаться с заглавной буквы.

Этот документ автоматически распознаётся движком как определение QML-типа. Кроме того, тип, определённый таким образом, автоматически становится доступным другим QML-файлам в той же директории, поскольку движок ищет в непосредственной директории при разрешении имён QML-типов.

Определение пользовательского QML-типа

Например, ниже представлен документ, объявляющий Прямоугольник с дочерним Областью мыши. Документ был сохранён в файл с именем SquareButton.qml.

// SquareButton.qml
import QtQuick 2.0

Rectangle {
    property int side: 100
    width: side; height: side
    color: "red"

    MouseArea {
        anchors.fill: parent
        onClicked: console.log("Button clicked!")
    }
}

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

// myapplication.qml
import QtQuick 2.0

SquareButton {}

Это создаёт красный Прямоугольник размером 100x100 с внутренней Областью мыши, как определено в SquareButton.qml. Когда этот myapplication.qml документ загружается движком, он загружает документ SquareButton.qml как компонент и создаёт объект SquareButton.

Тип SquareButton инкапсулирует дерево QML-объектов, объявленных в SquareButton.qml. Когда QML-движок создаёт объект SquareButton из этого типа, он создаёт объект из дерева Прямоугольников, определённого в SquareButton.qml.

Примечание: регистр букв имени файла имеет значение на некоторых файловых системах (особенно UNIX). Рекомендуется, чтобы регистр имени файла точно соответствовал регистру желаемого имени QML-типа — например, Box.qml, а не BoX.qml — независимо от платформы, на которой будет развернут QML-тип.

Встроенные компоненты

Иногда создание нового файла для типа может быть неудобно, например, при повторном использовании небольшого делегата в нескольких представлениях. Если вам не нужно на самом деле экспонировать тип, а только создать экземпляр, Component — это вариант. Но если вы хотите объявить свойства с типами компонентов или использовать его в нескольких файлах, Component не подходит. В этом случае вы можете использовать встроенные компоненты. Встроенные компоненты объявляют новый компонент внутри файла. Синтаксис для этого:

component <component name> : BaseType {
    // declare properties and bindings here
}

Внутри файла, объявляющего встроенный компонент, к типу можно обратиться просто по имени.

// Images.qml
import QtQuick 2.15

Item {
    component LabeledImage: Column {
        property alias source: image.source
        property alias caption: text.text

        Image {
            id: image
            width: 50
            height: 50
        }
        Text {
            id: text
            font.bold: true
        }
    }

    Row {
        LabeledImage {
            id: before
            source: "before.png"
            caption: "Before"
        }
        LabeledImage {
            id: after
            source: "after.png"
            caption: "After"
        }
    }
    property LabeledImage selectedImage: before
}

В других файлах он должен предваряться именем содержащего его компонента.

// LabeledImageBox.qml
import QtQuick 2.15

Rectangle {
    property alias caption: image.caption
    property alias source: image.source
    border.width: 2
    border.color: "black"
    Images.LabeledImage {
        id: image
    }
}

Примечание: встроенные компоненты не делят свою область видимости с компонентом, в котором они объявлены. В следующем примере, когда A.MyInlineComponent в файле B.qml будет создан, произойдёт ошибка ReferenceError, так как root не существует как идентификатор в B.qml. Поэтому не рекомендуется ссылаться на объекты в встроенном компоненте, которые не являются частью его.

// A.qml
import QtQuick 2.15

Item {
    id: root
    property string message: "From A"
    component MyInlineComponent : Item {
        Component.onCompleted: console.log(root.message)
    }
}
// B.qml
import QtQuick 2.15

Item {
    A.MyInlineComponent {}
}

Примечание: Встроенные компоненты не могут быть вложены.

Импорт типов, определённых вне текущей директории

Если SquareButton.qml не находился в той же директории, что и myapplication.qml, то тип SquareButton необходимо было сделать доступным через оператор import в myapplication.qml. Его можно импортировать из относительного пути на файловой системе или как установленный модуль; см. модуль для получения дополнительной информации.

Доступные атрибуты пользовательских типов

Определение корневого объекта в файле .qml определяет атрибуты, доступные для QML-типа. Все свойства, сигналы и методы, принадлежащие этому корневому объекту — будь то пользовательские объявления или свойства QML-типа корневого объекта — являются внешне доступными и могут быть читаемы и изменены для объектов этого типа.

Например, тип корневого объекта в файле SquareButton.qml — Прямоугольник. Это означает, что все свойства, определённые типом Прямоугольник, могут быть изменены для объекта SquareButton. Нижеприведённый код определяет три SquareButton объекта со специфическими значениями для некоторых свойств корневого объекта Прямоугольник типа SquareButton.

// application.qml
import QtQuick 2.0

Column {
    SquareButton { side: 50 }
    SquareButton { x: 50; color: "blue" }
    SquareButton { radius: 10 }
}

Атрибуты, доступные для объектов пользовательского QML-типа, включают все пользовательские свойства, методы и сигналы, которые дополнительно были определены для объекта. Например, предположим, что Прямоугольник в SquareButton.qml был определён следующим образом, с дополнительными свойствами, методами и сигналами:

// SquareButton.qml
import QtQuick 2.0

Rectangle {
    id: root

    property bool pressed: mouseArea.pressed

    signal buttonClicked(real xPos, real yPos)

    function randomizeColor() {
        root.color = Qt.rgba(Math.random(), Math.random(), Math.random(), 1)
    }

    property int side: 100
    width: side; height: side
    color: "red"

    MouseArea {
        id: mouseArea
        anchors.fill: parent
        onClicked: root.buttonClicked(mouse.x, mouse.y)
    }
}

Любой объект SquareButton может использовать свойство pressed, сигнал buttonClicked и метод randomizeColor(), которые были добавлены к корневому объекту Прямоугольник:

// application.qml
import QtQuick 2.0

SquareButton {
    id: squareButton

    onButtonClicked: {
        console.log("Clicked", xPos, yPos)
        randomizeColor()
    }

    Text { text: squareButton.pressed ? "Down" : "Up" }
}

Обратите внимание, что любые значения id , определённые в SquareButton.qml, недоступны для объектов SquareButton, так как значения id доступны только в рамках области видимости компонента, в котором объявлен компонент. Определённый выше объект SquareButton не может обратиться к mouseArea для обращения к дочернему элементу Область мыши, и если у него было бы значение id равное root вместо squareButton, это не создавало бы конфликта со значением id корневого объекта, определённого в SquareButton.qml, так как они объявляются в разных областях видимости.

© The Qt Company Ltd
Licensed under the GNU Free Documentation License, Version 1.3.
https://doc.qt.io/qt-5.15/qtqml-documents-definetypes.html

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API