mafulechka
mafulechka03 квітня 2020 р. 04:40

Нові можливості мови QML у Qt 5.15

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


Обов'язкові властивості (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.
• Ви можете використовувати тип компонента в об'явах властивостей.
• Ви можете посилатися на компонент інших файлів, відмінних від того, в якому він визначений.

Нульове об'єднання

Остання нова мовна функція була реалізована стажистом компанії 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).

Рекомендуємо хостинг TIMEWEB
Рекомендуємо хостинг TIMEWEB
Стабільний хостинг, на якому розміщується соціальна мережа EVILEG. Для проектів на Django радимо VDS хостинг.

Вам це подобається? Поділіться в соціальних мережах!

Коментарі

Only authorized users can post comments.
Please, Log in or Sign up
d
  • dsfs
  • 26 квітня 2024 р. 04:56

C++ - Тест 004. Указатели, Массивы и Циклы

  • Результат:80бали,
  • Рейтинг балів4
d
  • dsfs
  • 26 квітня 2024 р. 04:45

C++ - Тест 002. Константы

  • Результат:50бали,
  • Рейтинг балів-4
d
  • dsfs
  • 26 квітня 2024 р. 04:35

C++ - Тест 001. Первая программа и типы данных

  • Результат:73бали,
  • Рейтинг балів1
Останні коментарі
k
kmssr08 лютого 2024 р. 18:43
Qt Linux - Урок 001. Автозапуск програми Qt під Linux как сделать автозапуск для флэтпака, который не даёт создавать файлы в ~/.config - вот это вопрос ))
АК
Анатолий Кононенко05 лютого 2024 р. 01:50
Qt WinAPI - Урок 007. Робота з ICMP Ping в Qt Без строки #include <QRegularExpressionValidator> в заголовочном файле не работает валидатор.
EVA
EVA25 грудня 2023 р. 10:30
Boost - статичне зв&#39;язування в проекті CMake під Windows Ошибка LNK1104 часто возникает, когда компоновщик не может найти или открыть файл библиотеки. В вашем случае, это файл libboost_locale-vc142-mt-gd-x64-1_74.lib из библиотеки Boost для C+…
J
JonnyJo25 грудня 2023 р. 08:38
Boost - статичне зв&#39;язування в проекті CMake під Windows Сделал всё по-как у вас, но выдаёт ошибку [build] LINK : fatal error LNK1104: не удается открыть файл "libboost_locale-vc142-mt-gd-x64-1_74.lib" Хоть убей, не могу понять в чём дел…
G
Gvozdik18 грудня 2023 р. 21:01
Qt/C++ - Урок 056. Підключення бібліотеки Boost в Qt для компіляторів MinGW і MSVC Для решения твой проблемы добавь в файл .pro строчку "LIBS += -lws2_32" она решит проблему , лично мне помогло.
Тепер обговоріть на форумі
Evgenii Legotckoi
Evgenii Legotckoi02 травня 2024 р. 14:07
Мобильное приложение на C++Qt и бэкенд к нему на Django Rest Framework Добрый день. По моему мнению - да, но то, что будет касаться вызовов к функционалу Андроида, может создать огромные трудности.
IscanderChe
IscanderChe30 квітня 2024 р. 04:22
Во Flask рендер шаблона не передаётся в браузер Доброе утро! Имеется вот такой шаблон: <!doctype html><html> <head> <title>{{ title }}</title> <link rel="stylesheet" href="{{ url_…
G
Gar22 квітня 2024 р. 05:46
Clipboard Как скопировать окно целиком в clipb?
Павел Дорофеев
Павел Дорофеев14 квітня 2024 р. 02:35
QTableWidget с 2 заголовками Вот тут есть кастомный QTableView с многорядностью проект поддерживается, обращайтесь
f
fastrex04 квітня 2024 р. 04:47
Вернуть старое поведение QComboBox, не менять индекс при resetModel Добрый день! У нас много проектов в которых используется QComboBox, в версии 5.5.1, когда модель испускает сигнал resetModel, currentIndex не менялся. В версии 5.15 при resetModel происходит try…

Слідкуйте за нами в соціальних мережах