Форум программистов, компьютерный форум, киберфорум
Wyn
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  

Полезности QML

Запись от Wyn размещена 29.04.2016 в 15:21
Показов 3413 Комментарии 0
Метки c++, javascript, qt qml

Общий QML

Оглавление
  1. Основы
    1. Правила QML
    2. Свойства и соединения
    3. Динамическое создание объектов
    4. JavaScript
    5. Перевод приложения
  2. Взаимодействие между QML и C++
    1. Основы
      1. Нерегистрируемые в QML объекты
      2. Регистрируемые в QML объекты
    2. Реализация специфичных для QML типов и аттрибутов
      1. Прикреплённые объекты и аннотации
      2. Модификаторы свойств
      3. Определение свойства по-умолчанию для QML-объектов в С++
      4. Получение уведомлений об инициализации объекта
  3. Рекомедации
    1. Общие рекомендации
    2. Оформление кода
    3. Масштабируемость
    4. Оптимизации
  4. Полезности
    1. Общие
      1. Двунаправленное соединение
      2. Скрытые свойства в подключаемом элементе
      3. Неизменяемое снаружи свойство в подключаемом элементе, которое можно изменять внутри
      4. Реализация класса асинхронной загрузки изображений
    2. Работа с компонентами
      1. StackView(controls1)
  5. Специфика платформ(пока нет)
    1. Android
    2. iOS
    3. Linux
    4. Windows
  6. Список ссылок и литературы

Полезности

Общие
Двунаправленное соединение

Используя связки рано или поздно возникает потребность в двунаправленном соединении для актуальности свойств(property) при их редактировании где-нибудь. К сожалению в QML нет по умолчанию двунаправленного соединения. Можно его организовать несколькими способами, но практически все они при некоторых условиях дают сбой. Единственное найденное мной рабочее решение заключается в использовании Binding и прямых js-присваиваний. Это может не быть особенно быстрым из-за постоянного вызова js-контекста, но _оно_работает_.
Приведу простой пример двунаправленного соединения из двух элементов и свойства:
JavaScript
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
// main.qml
import QtQuick 2.5
import QtQuick.Controls 1.4
 
ApplicationWindow {
    id: root
 
    property int prop
 
    onPropChanged: console.log("Main prop changed to " + prop)
 
    visible: true
    width: 640
    height: 480
 
    SpinBox {
        id: spinBox
 
        Binding on value { value: root.prop }
 
        onValueChanged: if (root.prop !== value) root.prop = value
    }
 
    StackView {
        id: stack
 
        anchors.top: spinBox.bottom
        anchors.bottom: parent.bottom
        width: parent.width
        initialItem: initItem
    }
 
    Item {
        visible: false
 
        Test2 {
            id: initItem
 
            Binding on prop { value: root.prop }
 
            onPropChanged: if (root.prop !== prop) root.prop = prop
        }
    }
}
JavaScript
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
// Test2.qml
import QtQuick 2.5
import QtQuick.Controls 1.4
 
Item {
    id: root
 
    property int prop
 
    onPropChanged: console.log("Test 2 prop changed to " + prop)
 
    SpinBox {
        id: spinbox
 
        Binding on value { value: root.prop }
 
        onValueChanged: if (root.prop !== value) root.prop = value
    }
}

Скрытые свойства в подключаемом элементе
Любые свойства, расположенные в подэлементах, не видны при подключении элемента. Зная это можно воспользоваться QML-примитивом QtObject, чтобы хранить там скрытые свойства.
JavaScript
1
2
3
4
5
6
7
8
9
10
11
12
13
// MyElement.qml
import QtQuick 2.5
 
Item {
    id: root
 
    property int x1 // данное свойство будет видно при подключении элемента MyElement
 
    QtObject {
        id: d
 
        property int x2 // данное свойство не будет видно при подключении элемента MyElement
    }

Неизменяемое снаружи свойство в подключаемом элементе, которое можно изменять внутри
По документации свойство может или быть readonly или не быть. Но что делать, если для подключаемого элемента нужно сделать свойство, состояние которого должно быть видно снаружи, но которое должно меняться только внутри элемента? В данный момент есть один обходной путь, который не факт что будет работать завтра. Путь заключается в том, чтобы использовать readonly alias на обычное скрытое свойство
JavaScript
1
2
3
4
5
6
7
8
9
10
11
12
13
// MyElement.qml
import QtQuick 2.5
 
Item {
    id: root
 
    readonly property alias x1: d.x2 // "виртуальное" свойство x1 изменять нельзя, зато свойство d.x2 - можно.
 
    QtObject {
        id: d
 
        property int x2 // данное свойство не будет видно при подключении элемента MyElement
    }

Реализация класса асинхронной загрузки изображений

C++ (Qt)
1
2
3
4
5
6
7
8
9
10
 // main.cpp
int main(int argc, char *argv[])
{
    QGuiApplication app(argc, argv);
    QQmlApplicationEngine engine;
    AsyncImageProvider *asyncImageProvider = new AsyncImageProvider();
    engine.addImageProvider("asyncImage", asyncImageProvider);
    engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
    return app.exec();
}
C++ (Qt)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
 // asyncimageprovider.h
#ifndef ASYNCIMAGEPROVIDER_H
#define ASYNCIMAGEPROVIDER_H
 
#include <QQuickAsyncImageProvider>
#include <QThreadPool>
 
class AsyncImageResponse : public QQuickImageResponse, public QRunnable
{
public:
    AsyncImageResponse(const QString &id, const QSize &requestedSize);
 
    QQuickTextureFactory *textureFactory() const;
    void run();
 
private:
    QString m_id;
    QSize m_requestedSize;
    QQuickTextureFactory *m_texture;
};
 
class AsyncImageProvider : public QQuickAsyncImageProvider
{
public:
    QQuickImageResponse *requestImageResponse(const QString &id, const QSize &requestedSize);
 
private:
    QThreadPool m_pool;
};
 
#endif // ASYNCIMAGEPROVIDER_H
C++ (Qt)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
 // asyncimageprovider.cpp
#include "asyncimageprovider.h"
#include <QImage>
 
AsyncImageResponse::AsyncImageResponse(const QString &id, const QSize &requestedSize)
    : QQuickImageResponse(), QRunnable(),
      m_id(id), m_requestedSize(requestedSize), m_texture(0)
{
    setAutoDelete(false);
}
 
QQuickTextureFactory *AsyncImageResponse::textureFactory() const
{
    return m_texture;
}
 
void AsyncImageResponse::run()
{
    QImage image(m_id);
    if (m_requestedSize.isValid())
        image = image.scaled(m_requestedSize, Qt::KeepAspectRatio);
    m_texture = QQuickTextureFactory::textureFactoryForImage(image);
    emit finished();
}
 
QQuickImageResponse *AsyncImageProvider::requestImageResponse(const QString &id, const QSize &requestedSize)
{
    AsyncImageResponse *response = new AsyncImageResponse(id, requestedSize);
    m_pool.start(response);
    return response;
}


Работа с компонентами
StackView(controls1, частично устарело)

StackView это один из основных компонентов для мобильной разработки Именно на нём базируется смена окон в мобильном приложении. В общем и целом с ним довольно просто работать. Рекомендации:
- StackView и элементы, которые в него загружаются, лучше располагать прямо в main.qml, там же держать и всю логику работы с ним.
- Элементы во время анимации смены экрана лучше выключать.
- Чтобы не делать в каждом элементе одинаковые строки возвращения, лучше создать класс-контейнер, содержащий строку возвращения и оборачивать элементы в него.
- Существует некоторая проблема с возвращением фокусировки на stackView после вызова диалога. Проблема решается или созданием самоудаляющегося диалога, или прописыванием в обработчика onVisibleChanged у диалога принудительной фокусировки на stackView. Учитывая, что диалог может вызываться где угодно, а со stackView обычно работают в main.qml, то я рекомендую использовать самоудаляющиеся диалоги.
Пример

main.qml
JavaScript
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
import QtQuick 2.5
import QtQuick.Window 2.2
import QtQuick.Controls 1.4
 
Window {
    id: root
 
    visible: true
    height: 600
    width: 800
    title: qsTr("StackView Example")
 
    StackView {
        id: stackView
 
        anchors.fill: parent
        focus: true
        initialItem: mainElement
 
        Keys.onReleased: if (event.key === Qt.Key_Back && stackView.depth > 1) { // реализация возврата на предыдущее окно
                             stackView.pop()                                                                    // при нажатии Key_Back
                             event.accepted = true
                         }
    }
 
    MainElement {
        id: mainElement
 
        enabled: Stack.status === Stack.Active
    }
 
}
Метки c++, javascript, qt qml
Размещено в Qt, QML
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Всего комментариев 0
Комментарии
 
Новые блоги и статьи
Новый ноутбук
volvo 07.12.2025
Всем привет. По скидке в "черную пятницу" взял себе новый ноутбук Lenovo ThinkBook 16 G7 на Амазоне: Ryzen 5 7533HS 64 Gb DDR5 1Tb NVMe 16" Full HD Display Win11 Pro
Музыка, написанная Искусственным Интеллектом
volvo 04.12.2025
Всем привет. Некоторое время назад меня заинтересовало, что уже умеет ИИ в плане написания музыки для песен, и, собственно, исполнения этих самых песен. Стихов у нас много, уже вышли 4 книги, еще 3. . .
От async/await к виртуальным потокам в Python
IndentationError 23.11.2025
Армин Ронахер поставил под сомнение async/ await. Создатель Flask заявляет: цветные функции - провал, виртуальные потоки - решение. Не threading-динозавры, а новое поколение лёгких потоков. Откат?. . .
Поиск "дружественных имён" СОМ портов
Argus19 22.11.2025
Поиск "дружественных имён" СОМ портов На странице: https:/ / norseev. ru/ 2018/ 01/ 04/ comportlist_windows/ нашёл схожую тему. Там приведён код на С++, который показывает только имена СОМ портов, типа,. . .
Сколько Государство потратило денег на меня, обеспечивая инсулином.
Programma_Boinc 20.11.2025
Сколько Государство потратило денег на меня, обеспечивая инсулином. Вот решила сделать интересный приблизительный подсчет, сколько государство потратило на меня денег на покупку инсулинов. . . .
Ломающие изменения в C#.NStar Alpha
Etyuhibosecyu 20.11.2025
Уже можно не только тестировать, но и пользоваться C#. NStar - писать оконные приложения, содержащие надписи, кнопки, текстовые поля и даже изображения, например, моя игра "Три в ряд" написана на этом. . .
Мысли в слух
kumehtar 18.11.2025
Кстати, совсем недавно имел разговор на тему медитаций с людьми. И обнаружил, что они вообще не понимают что такое медитация и зачем она нужна. Самые базовые вещи. Для них это - когда просто люди. . .
Создание Single Page Application на фреймах
krapotkin 16.11.2025
Статья исключительно для начинающих. Подходы оригинальностью не блещут. В век Веб все очень привыкли к дизайну Single-Page-Application . Быстренько разберем подход "на фреймах". Мы делаем одну. . .
Фото: Daniel Greenwood
kumehtar 13.11.2025
Расскажи мне о Мире, бродяга
kumehtar 12.11.2025
— Расскажи мне о Мире, бродяга, Ты же видел моря и метели. Как сменялись короны и стяги, Как эпохи стрелою летели. - Этот мир — это крылья и горы, Снег и пламя, любовь и тревоги, И бескрайние. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2025, CyberForum.ru