Spec-Zone.ru › Qt

Определение типов объектов с помощью документов 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 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 не существует как id в 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 необходимо было бы сделать его доступным через оператор импорта в 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: (mouse)=> root.buttonClicked(mouse.x, mouse.y)
    }
}

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

// application.qml
import QtQuick 2.0

SquareButton {
    id: squareButton

    onButtonClicked: (xPos, yPos)=> {
        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-6.2/qtqml-documents-definetypes.html

Spec-Zone.ru

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