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:
- 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;
- 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;
- 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 } }
Добрый день интересует такой вопрос. С помощью QML возможно ли создавать многооконные приложения? Есть ли аналоги MDI area? Гугл не помогает, в документации только однооконные приложения с регистрацией в main.cpp. Какая практика вообще существует использования qml в создании больших приложений (многооконных).
День добрый!!
В QML нет аналога MDI area, но можно сделать стандартный проект на QWidget, добавить в главное окно QMdiArea, а в него добавлять QML-ки в качестве виджетов через QQuickWidget. Вот статья для примера, как отобразить виджет с QML в проекте на QWidget .
Вот и я тоже пришел к такому же выводу, стандартное QWidget как обертка для QuickWidget-ов. А вообще практика применения QML для десктопов видимо такая же, я не нашел информации на этот счет вообще .
Я не встречался с повсеместным использованием QML для десктопа, если приложение также не затачивается на работу под мобильные платформы. Видимо, поэтому и MDI area до сих пор не существует для QML, поскольку имеет крайне низкий приоритет.
Добрый день! Благодарю за хороший пример, только его бы дополнить немного: что если мне нужно из фрагментов "Fragment 1.qml" - "Fragment 2.qml" посылать сигналы, причём набор сигналов разный. Как это лучше организовать, какие тут есть варианты?
P.S. Сам спросил - сам отвечаю: :)
Another variant: move above logic inside
and call these functions via property like this:Добрый день. Не успел Вам ответить ))
Для ответа на ваш вопрос, по моему мнению лучше было бы объединить всю информациб о сигналах и слотах, которая присутсвует на сайте.
Поэтому я первоначально потратил время на подготовку статьи, касательно вашего вопроса.
Можете прочитать здесь QML - Урок 036. Работа с сигналами и слотами в QML .
Надеюсь, что найдёте ещё что-нибудь дополнительное для себя.
Благодарю!
Всем привет. А есть ли возможность динамически загрузить qml файл, который скачивается во время работы программы и помещается в определённую папку на диске C?
Да можно, нужно указать относительный путь к qml файлу
добрый день, грамотно ли использовать loader для загрузки небольших диалоговых окон по клику из меню? и если да, то возникает проблема: загрузили первое диалоговое окно, потом его закрыли, а открыть снова получается только после згразки другого д.о. Проблема в свойтве status?
Лично для меня loader - это компонень, который загружает какую-то часть внутри окна, поэтому с этой точки зрения я бы не стал рассматривать использование loader лоя открытия окон, только для заполнения этих окон контентом.