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

Полезности QML

Запись от Wyn размещена 29.04.2016 в 15:21
Показов 3704 Комментарии 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
Комментарии
 
Новые блоги и статьи
мат медиц модель 30. презентация проекта
anaschu 27.08.2026
хоп хоп хоп хидахоп, а я кладую))
Как у меня протекала болезнь
zorxor 27.08.2026
Здравствуйте, друзья! Эта запись блога предназначена именно для вас - для моих дорогих друзей, которые знали меня лично. Чтобы ответить на вопрос - а что же со мной произошло на самом деле? Я учился. . .
Нашел вот забавное видео о измерениях. Лучшее что я видел на эту тему
kumehtar 26.08.2026
ILETXiw9bMQ Основная суть и тезисы по измерениям: 0D (Нулевое измерение): точка, не имеющая длины, ширины, высоты или объема. Объект не может перемещаться в 0D. 1D (Первое измерение):. . .
[EasyBuilder Pro] Памятка по разработке для панелей Weintek
ФедосеевПавел 26.08.2026
Памятка по разработке для панелей Weintek ВВЕДЕНИЕ Ранее, при реализации проектов основное внимание уделял разработке управляющей программы для контроллера, а панели оператора доставалось время. . .
Модель по догадкам
anaschu 25.08.2026
Прошло две недели. Я уже рассказывал, как разговаривал с сотрудниками у сортировки и как понял, что главная ветка — не про приёмку, а про отбор. Но тогда я думал, что понял механику. На этой неделе я. . .
Запись в регистр сведений независимо от заполненности табличной части
Maks 25.08.2026
Реализация из решения ниже выполнена на нетиповом документе с несколькими табличными частями, разработанного в КА2. Задача: Обеспечить запись документа в регистр сведений независимо от. . .
Ноутбук Альфария
kumehtar 24.08.2026
Встретился тут в сети ноутбук Альфария, примарха Альфа-Легиона. Хотя возможно, это ноутбук Омегона, разумеется. Ну как вам?
Мастера простых решений
DevAlt 23.08.2026
В сишарп стэках winforms, да и wpf существует сложная система связывания источниках данных и элементов формы(текстовые поля и метки), опирается все это на технологию событий и мета. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru