📜 ⬆️ ⬇️

Tree mapping in qml

image
Once one of my friends asked: "How can I display a tree structure in qml?" I already tried to publish the resulting version on Habré, but that time I oversaw an invite ... Under the cut, the second attempt was to publish an article.
Objective: to develop a test application displaying a tree structure with Qt Quick.
The result can be viewed on GitHub: github.com/1KoT1/QMLPresentTree

Data structure of the application

In our application, tree elements are described by the TreeItem class.

image

The content property stores some element content. For the test application is quite suitable string.
Each element instance has a list of sub-elements contained in it - childItems. Thus a tree is built.
The isOpen property stores the state of the list of internal elements: expanded or hidden.
The hasChild property indicates whether there are any children. It would have been possible to do using! Item.childItems (). IsEmpty (), but for ease of further use I entered the hasChild field.
For code implementing this class, see treeitem.h and treeitem.cpp .
Model.h and model.cpp describe the data model of the application. The model contains the only property - the tree of elements.
In main.cpp I create a model, a view and export the model to qml. The controller is missing, since there is no functionality other than the display.
')
Tree mapping in qml

Now we come to the most interesting. We describe the mapping of our tree structure using qml.
The main qml file contains the following code:

import QtQuick 2.0 Rectangle { width: 360 height: 360 ListView{ anchors.fill: parent model: programmModel.tree delegate: ItemView{} } } 


The basic idea is as follows: Display a flat list of first-level items. The delegate describing the element contains a flat list for displaying sub-elements. And so on. On the structure of the tree.

The entire window is filled with a ListView element. ListView displays a flat list and allows you to scroll through it. As a model, I specify our tree. In essence, this is a flat list of elements, each of which in turn contains a list of sub-elements. The display of each item is described in ItemView.qml :

 import QtQuick 2.0 Row{ id: itemView Text{ width: 10 height: 10 text: modelData.hasChild? modelData.isOpen ? "-" : "+" : "" MouseArea{ anchors.fill: parent onClicked: modelData.isOpen = !modelData.isOpen; } } Column{ Text{ text: modelData.content } Loader{ source: modelData.isOpen ? "TreeItemsList.qml" : "Empty.qml" } } } 


The element consists of the content output:

 Text{ text: modelData.content } 


A control showing the presence of sub-elements and allowing the list to be expanded:

 Text{ width: 10 height: 10 text: modelData.hasChild? modelData.isOpen ? "-" : "+" : "" MouseArea{ anchors.fill: parent onClicked: modelData.isOpen = !modelData.isOpen; } } 


List of items:

 Loader{ source: modelData.isOpen ? "TreeItemsList.qml" : "Empty.qml" } 


The list of sub-items should only be displayed when it is open. To do this, use the element Loader. In the closed state, Empty.qml is loaded into it - a rectangle of size 0 by 0. The display of the open list of sub-elements is described in TreeItemsList.qml .

Consider it:

 import QtQuick 2.0 Column{ Repeater{ model: modelData.childItems delegate: ItemView{} } } 


Building a vertical list is done using a combination of the Column and Repeater elements. Unlike ListView Column does not allow scrolling content and takes all the necessary space to display internal elements. The entire tree is scrolled by using the ListView in the main file.

To display the sub-elements, the same delegot is used as in the top level list. Thus, each element can display its elements. Nesting is limited only by system resources.

Thanks to the approach used, another important requirement is fulfilled: the visual tree is built only for open elements, i.e., unnecessary system resources are not wasted.

Source: https://habr.com/ru/post/197110/


All Articles