mafulechkaApril 3, 2020, 4:40 a.m.

Новые возможности языка QML в Qt 5.15

В то время, как в Qt 6.0 ожидаются большие изменения, QML уже получил некоторые новые языковые возможности в 5.15. Читайте дальше, чтобы узнать об обязательных свойствах, встроенных компонентах и nullish coalescing.

ADS

Обязательные свойства (Required Properties)

Иногда у вас есть компоненты, которые требуют установки какого-либо свойства, и в действительности не имеют хороших значений по умолчанию. Например, вы можете позаботиться о доступности ваших кнопок, поэтому вы создаёте AccessibleButton, у которого всегда должно быть описание.

// AccessibleButton.qml
Button {
    property string description
    Accessible.description: description
}

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

AccessibleButton {
    onClicked: (mouse)  => { /* fancy business logic here */ }
}

Описание теперь просто пустая строка! Конечно, вы могли бы дать ей значение по умолчанию, но какое именно? "Button" («Кнопка»)? Вряд ли это полезно. "Не должны ли вы сообщить об этом"? По крайней мере, тестирование может это обнаружить. Но не будет ли более полезным, если механизм QML будет знать, что это свойство нужно установить?

До Qt 5.15, к сожалению, не было возможности обеспечить, чтобы описание было установлено. Но начиная с Qt 5.15 это становится возможным:

Button {
    required property string description
    Accessible.description: description
}

Теперь, если AccessibleButton создан, а описание не задано, все приложение не запустится. Это, однако, не может быть сделано, если компонент создается динамически, например, через Loader. В этом случае будет только предупреждение во время выполнения.

Также планируется добавить дополнительную поддержку инструментов в qmllint и QtCreator, чтобы показывать предупреждение, если требуемые свойства не установлены.

Обязательные свойства и делегаты (Delegates)

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

ListView {
    model: root.myModel
    delegate: Text {
        id: delegate
        color: index % 2 ? "gray" : "black"
        text: description
    }
}

И, если ваши делегаты не содержат обязательных свойств, здесь ничего не меняется. Однако, если они содержат хотя бы одно обязательное свойство, эти имена больше недоступны. Вместо этого вы должны точно выбрать, указав их, как обязательные свойства.

ListView {
    model: root.myModel
    delegate: Text {
        id: delegate
        required property int index
        required property string description
        color: index % 2 ? "gray" : "black"
        text: description
    }
}

Затем механизм QML установит обязательные свойства. Обратите внимание, что между новым подходом и старым есть одно существенное различие в том случае, если ваша модель была редактируемой: при старом подходе вы могли бы написать:

Text {
    id: delegate
    Component.onCompleted: description = "My fancy new text"
}

и модель, соответственно, была бы обновлена. Но если вы делаете,

Text {
    id: delegate
    required property string description
    Component.onCompleted: delegate.description = "My fancy new text"
}

тогда привязка к описанию будет нарушена (и механизм QML выведет предупреждение), и модель не будет обновлена. Такое поведение было выбрано, чтобы гарантировать, что компоненты не будут вести себя слишком по-разному при использовании в делегатах и при их использовании вне их. Кроме того, разработчики не хотели никого поощрять делать обязательные присваивания свойствам (поскольку это нарушает привязки в целом).

Если вы, действительно, хотите обновить значение модели, конечно, есть способ достичь этого: сделать модель обязательным свойством и написать:

Component.onCompleted: model.description= "My fancy new text"

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

Встроенные компоненты (Inline Components)

Еще одна новая функция в 5.15 - встроенные компоненты. Как следует из названия, они позволяют вам определить новый компонент внутри файла. Основной синтаксис это:

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

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

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

Вы можете поинтересоваться, зачем нужны встроенные компоненты, когда QML уже имеет тип Component. Глядя на предыдущие примеры, можно видеть, что встроенные компоненты позволяют вам делать следующие вещи, которые Component не делает:

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

Nullish Coalescing

Последняя новая языковая функция была реализована стажером компании Qt Максимилианом Гольдштейном. Хотя QML обычно поддерживает только EcmaScript 6, Макс добавил поддержку для новой языковой функции, которая в настоящее время находится в процессе добавления к последнему стандарту EcmaScript: nullish coalescing . Цитируя MDN:

nullish coalescing operator - это логический оператор, который возвращает свой правый операнд, когда его левый операнд равен нулю или не определен, или, в противном случае, возвращает свой левый операнд.

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

Item {
    property var settings
    property int brightness: settings.brightness ?? 100
    property color color: settings.color ?? "blue"
    Component.onCompleted: settings = JSON.parse(settingsString)
}

Обратите внимание, что нельзя было использовать || вместо ?? для brightness (яркости), так как settings.brightness мог бы быть 0, в этом случае получили бы значение по умолчанию.

Ожидайте!

С Qt 6 на горизонте, многие другие изменения обязательно появятся в QML. Помимо модернизации внутренних компонентов механизма QML, разработчики хотят использовать статическую типизацию, как для генерирования более быстрого кода (включая компиляцию в C++), так и для улучшения инструментов. Более того, хотя разработчики концентрируются на этих крупных темах для начального выпуска 6.0, они сохраняют открытость относительно небольших улучшений качества жизни: необязательное создание цепочки или добавление поддержки для API выборки - это всего лишь два примера запросов функций от сообщества, рассматривается более крупная временная шкала 6.x (но не начальная версия 6.0).

We recommend hosting TIMEWEB
We recommend hosting TIMEWEB
Stable hosting, on which the social network EVILEG is located. For projects on Django we recommend VDS hosting.
Support the author Donate

Comments

Only authorized users can post comments.
Please, Log in or Sign up
Timeweb

Let me recommend you the excellent hosting on which EVILEG is located.

For many years, Timeweb has been proving his stability.

For projects on Django I recommend VDS hosting

View Hosting
y

C ++ - Test 004. Pointers, Arrays and Loops

  • Result:50points,
  • Rating points-4
n

C++ - Test 005. Structures and Classes

  • Result:41points,
  • Rating points-8
s

C++ - Тест 003. Условия и циклы

  • Result:42points,
  • Rating points-8
Popular publications in the last 90 Days
Last comments
f
  • fryn3
  • Oct. 21, 2021, 5:24 a.m.

QML - Tutorial 038. Using the clip property to crop child objects inside Item or Rectangle

Зачем внутри OpacityMask Item, почему сразу Rectangle не вставить? И что за rect.adapt? Мое предложение: layer.enabled: true layer.effect: OpacityMask { …
s

Qt/C++ - Lesson 060. Configuring the appearance of the application in runtime

Добрый вечер, на "лету" не работает, только перезапуск
s

Qt/C++ - Lesson 060. Configuring the appearance of the application in runtime

Спасибо, завтра опробую и отпишусь по результату

Django - Tutorial 007. Adding Pagination based on django-bootstrap3

Просто список каких-нибудь объектов передавайте, который дёрнули ищ api стороннего сервера from django.core.paginator import Paginatorobjects = ['john', 'paul', 'george', 'ringo']p = Pagina…
b

PyQt5 - Tutorial 009. Using QThread with MoveToThread

Спасибо большое
Now discuss on the forum
o

Применение стилей *.qss к собственным виджетам.

или взять код отсюда пример переписать его под свои нужды
j
  • juvf
  • Oct. 21, 2021, 7:31 a.m.

Qt Quick Virtual Keyboard

В QtCreator есть пример на QML с виртуальной клавиатурой "Qt Quick Virtual Keyboard - Basic Example". Собрал, работает. Собрал свой хеловорд свою программу состоящую из главного окна …

QScrollArea dynamically add QCheckBoxes

Всё правильно. Это просто спамер, который отправился в вечный бан.
  • Nomad
  • Oct. 15, 2021, 6:39 a.m.

Вопрос из раздела "как реализовать"

Всем привет. Есть бизнес логика которую надо реализовать на джанге, она состоит в следующем: надо реализовать функционал регистрации/авторизации компаний у которого есть свой дашборд …

Проблема с созданием файлов перевода для составного проекта

Я имею ввиду, если у вас был старые ts файлы, то написать парсер, который составил бы словарь переводов. Например. "Hello world" - "Привет мир" "Hello dev" - "Привет dev" и…
About
Services
© EVILEG 2015-2021
Recommend hosting TIMEWEB