QML - Lesson 018. Loader in QML Qt – The working with the dynamic components

Qt, QML, QtQuick, Loader

For the organization of the dynamic components of the change is convenient to use a Loader component, which is included in QML QtQuick and is a container for components in your application, let's say that you need to periodically replace the interface.

To draw an analogy, for example, with the development of Java for Android , there is a system of fragments, which can also be replaced in the container for them, following the logic of your application. For example, we click on the button and in a particular container, we replaced one fragment of another, and if we click on another button, then there is a third fragment, which replaces the second fragment is.

Therefore, make an application that will have 5 buttons and pressing each button in the Loader fragments will vary.

The structure of the project to work with the Loader

  • QmlLoader.pro - the profile of the project;
  • main.cpp - the main file of the application source code;
  • main.qml - basic qml code file;
  • Fragment1.qml - the first fragment for replacement Loader;
  • Fragment2.qml - second fragment;
  • Fragment3.qml - a third fragment.

main.cpp is created by default and is not subject to change, so it will not be given a listing, as well as the project profile.

main.qml

Installing components in the Loader can be done in several ways:

  1. A source property - in this case the component is a QML file and its contents is limited scope in terms of interaction with other elements in main.qml file;
  2. Through sourceComponent property - in this case, set Component objects that are contained in the file main.qml and not limited scope when interacting with other objects in main.qml;
  3. Installation via setSource() method - in this case, it is possible to specify additional options for an object, such as opacity, but do not forget to reset these settings, or they persist even when you install a new component.

In the following the above, there is a layer with five buttons, the Loader object, which is a rectangular container in which to put our pieces. Working with its location in the application window is made as if it were an object of type Rectangle .

import QtQuick 2.5
import QtQuick.Controls 1.4
import QtQuick.Layouts 1.1

ApplicationWindow {
    visible: true
    width: 640
    height: 480
    title: qsTr("Hello World")

    // Layer with buttons that will change the fragments
    RowLayout {
        id: rowLayout
        anchors.top: parent.top
        anchors.left: parent.left
        anchors.right: parent.right
        anchors.margins: 5

        Button {
            text: qsTr("Fragment 1")
            // Download the component from a file
            onClicked: loader.source = "Fragment1.qml"
        }

        Button {
            text: qsTr("Fragment 2")
            // Loading setSource component through the method of installing the fragment parameters
            onClicked: loader.setSource("Fragment2.qml", {"opactity": 1 })
        }

        Button {
            text: qsTr("Fragment 3")
            // Loading setSource component through the method of installing the fragment parameters
            onClicked: loader.setSource("Fragment3.qml", {"opacity": 0.5})
        }

        Button {
            text: qsTr("Fragment 4")
            // Installing a fragment from the Component
            onClicked: loader.sourceComponent = fragment4
        }

        Button {
            text: qsTr("Fragment 5")
            // Installing a fragment from the Component
            onClicked: loader.sourceComponent = fragment5
        }
    }

    Loader {
        id: loader
        anchors.top: rowLayout.bottom
        anchors.left: parent.left
        anchors.right: parent.right
        anchors.bottom: parent.bottom
        anchors.topMargin: 5
        source: "Fragment1.qml"
    }

    // The fourth fragment as component
    Component {
        id: fragment4

        Rectangle {
            anchors.fill: parent
            color: "blue"

            Text {
                text: "Fragment 5"
                color: "white"
                anchors.top: parent.top
                anchors.right: parent.right
                anchors.margins: 50
                font.pixelSize: 30

                renderType: Text.NativeRendering
            }

        }
    }

    // The fifth fragment as component
    Component {
        id: fragment5

        Rectangle {
            anchors.fill: parent
            color: "black"

            Text {
                text: "Fragment 5"
                color: "white"
                anchors.top: parent.top
                anchors.right: parent.right
                anchors.margins: 50
                font.pixelSize: 30

                renderType: Text.NativeRendering
            }

        }
    }
}

Fragment1.qml and the remaining fragments

And other code fragments Fragment1.qml identical except that they all have a different background color.

import QtQuick 2.5

Rectangle {
    anchors.fill: parent
    color: "green"

    Text {
        text: "Fragment 1"
        color: "white"
        anchors.top: parent.top
        anchors.right: parent.right
        anchors.margins: 50
        font.pixelSize: 30

        renderType: Text.NativeRendering
    }

}

Conclusion

Video

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
S

Добрый день интересует такой вопрос. С помощью QML возможно ли создавать многооконные приложения? Есть ли аналоги MDI area? Гугл не помогает, в документации только однооконные приложения с регистрацией в main.cpp. Какая практика вообще существует использования qml в создании больших приложений (многооконных).

День добрый!!

В QML нет аналога MDI area, но можно сделать стандартный проект на QWidget, добавить в главное окно QMdiArea, а в него добавлять QML-ки в качестве виджетов через QQuickWidget. Вот статья для примера, как отобразить виджет с QML в проекте на QWidget .

 
То есть получается некий костыль. В принципе, можно сделать и собственную MDIArea для QML, теоретически... это не должно составить труда. Но нужно подумать. Там по идее, нужно лишь сделать возможности для обработки изменения размера объектов, которые будут представлять из себя эти самые окна. А также реализовать логику перетаскивания окон и скроллинга для этой MDI area.
 
Просто многооконные приложение можно без проблем создавать на QML, вопрос лишь в том, насколько удачно можно реализовать некоторые сложные структуры интерфейса наподобие древовидных списков и этой самой MDI area.
S

Вот и я тоже пришел к такому же выводу, стандартное QWidget как обертка для QuickWidget-ов. А вообще практика применения QML для десктопов видимо такая же, я не нашел информации на этот счет вообще .

Я не встречался с повсеместным использованием QML для десктопа, если приложение также не затачивается на работу под мобильные платформы. Видимо, поэтому и MDI area до сих пор не существует для QML, поскольку имеет крайне низкий приоритет.

t

Добрый день! Благодарю за хороший пример, только его бы дополнить немного: что если мне нужно из фрагментов "Fragment 1.qml" - "Fragment 2.qml" посылать сигналы, причём набор сигналов разный. Как это лучше организовать, какие тут есть варианты?

P.S. Сам спросил - сам отвечаю: :)

    Loader
    {
        onLoaded: {
            if(item.objectName == "Fragment1") { // Set object name to an item beforehand
                item.mySignal1.connect(targetObject.function1);
                item.mySignal2.connect(targetObject.function2);
            }
        }
    }

Another variant: move above logic inside

Fragment1.qml
and call these functions via property like this:

    property var LoaderParent: parent.parent
    ...
    onMySignal1:{
        LoaderParent.function1(params);
    }

Добрый день. Не успел Вам ответить ))
Для ответа на ваш вопрос, по моему мнению лучше было бы объединить всю информациб о сигналах и слотах, которая присутсвует на сайте.
Поэтому я первоначально потратил время на подготовку статьи, касательно вашего вопроса.
Можете прочитать здесь QML - Урок 036. Работа с сигналами и слотами в QML .
Надеюсь, что найдёте ещё что-нибудь дополнительное для себя.

t

Благодарю!

Comments

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

Hello, Dear Users of EVILEG!!!

If the site helped you, then support the development of the site financially, please.

You can do it by following ways:

Thank you, Evgenii Legotckoi

VZ
Nov. 17, 2019, 2:25 a.m.
Vladimir Zhitkovsky

Qt - Test 001. Signals and slots

  • Result:78points,
  • Rating points2
m
Nov. 17, 2019, 2:20 a.m.
masha16

C++ - Test 002. Constants

  • Result:50points,
  • Rating points-4
m
Nov. 17, 2019, 2:15 a.m.
masha16

C++ - Test 001. The first program and data types

  • Result:53points,
  • Rating points-4
Last comments
c
Nov. 17, 2019, 2:25 p.m.
cyberaxe77

Шикарно! Как обычно всё объясняется чётко, ясно и, по-возможности, кратко. Побольше бы контента по PyQt5...
GV
Nov. 16, 2019, 4:16 p.m.
Gibraltar Vol'framov

Разрешите узнать, как вы получили qt+qml приложение размером в 10мб(даже релизных). Дело в том, что пустое приложение, хоть и со стек вью, обходится мне на все 40мб пространства. Или же вы воспо…
b
Nov. 9, 2019, 8:28 a.m.
bastonc

спасибо ещё раз. огромное, за уделённое время
b
Nov. 9, 2019, 8:24 a.m.
bastonc

Спасибо Вам большое. Буду изучать.
Nov. 9, 2019, 5:58 a.m.
Evgenij Legotskoj

Добрый день. По первым двум вопросам вы найдёте ответ в этой статье - PyQt5 - Урок 008. Работа с QTableWidget (Обновление урока 006) Что касается последнего вопроса, то я вам…
Now discuss on the forum
Nov. 17, 2019, 12:30 p.m.
Mihail Sermjazhko

Взял этот код https://github.com/promixis/Code128/tree/master/src и сделал так m_Barcode = new Code128Item(); m_Barcode->setWidth( 200 ); m_Barcode->setHeight( 80 ); m_Barco…
s
Nov. 16, 2019, 5:58 a.m.
sladkoewka

Благодарю! Пойду читать всю эту документацию, чтобы понять, как это вообще работает и дальше мучать свой прогресс бар.
Nov. 15, 2019, 7:37 a.m.
Intruder

Евгений, почитав про эту проблему пришел к выводу, что либо нужно говорить очередь, либо все вернуть из библиотеки (dll в моем случае) в приложение, потому что в приложении все работает просто з…
Nov. 15, 2019, 6:06 a.m.
Evgenij Legotskoj

Ну тогда не знаю )) Я большую часть времени на C++ с Qt работаю, а PyQt5 у меня боком. Так что, чем можем помочь ))
H
Nov. 15, 2019, 5:18 a.m.
Hyperfish

Да, пробовал, с преобразованием int array[]={1,2,3,4,5,6,7} в jintArray(array). Если так, то программа компилируется без ошибок и предупреждений, но вываливается с ошибкой времени выполнени…
EVILEG
About
Services
© EVILEG 2015-2019
Recommend hosting TIMEWEB