Creating grouped menu with Qt Quick
-
I am planning to utilize Qt Quick's unique capabilities and create a flexible menu system.
A menu is supposed to consist of a simple hierarchy (tree). The most basic elements are groups.
These groups can have an arbitrary number of children (buttons). Usually the number of buttons is far greater than the number of groups.
When interacting with the application, the menu has to be able to add and remove elements dynamically as well as change parameters and therefore the appearance. An optional TextInput element acts as a filter. As soon as a user starts to type, buttons should (re-)appear.Example:
@
- Group 1
- Button 1
- Button 2
- Button 3
- Group 2
- Button 4
- Button 5
- Group 3
@
Clicking on a group element will make it collapse and hide all children. They will reappear as soon as the group is clicked again.
I have tried to implement this menu system in three different ways. However, they all have certain problems and downsides.
Attempt 1: create all instances
@
Flickable
Column
Group
Column
Button
Button
Button
Group
Column
Button
Button
Group
Column
@Objects are generated by the C++ program (creating instances of group / button components)
Pros: elements can be added and removed dynamically
Cons: high number of instances will result in bad performance. Creation might take sevaral seconds, scrolling becomes sluggish. There are just too many items.Attempt 2: Data Model with QList<QObject>
QuickGroup has Q_PROPERTY entries for caption, collapsed status and a list of QuickButton instances. A list of QuickGroups is passed via setContextProperty.
@
ListView
delegate: Group
...
@Pros: values can be modified on-the-fly and QML part is notified by signals
Cons: list will have to be retransmitted via setContextProperty() as soon as the number of elements changes -> ListView (might) jumpAttempt 3: Data Model with QAbstractItemModel
Pros: elements can be added and removed dynamically using beginInsertRow etc. Animations with ListView.onRemove and ListView.onAdd
Cons: Hierarchy? QAbstractItemModel appears to be list in QMLThe documentation mentions something about a hasModelChildren role property and changing the (root) model index.
However, I am not entirely sure if this is going to be of any use?Maybe there is a much easier and better way to solve this problem. Any help would be greatly appreciated!
- Group 1
-
I had similar problem some time ago. I've ended with your third version (with QAbstractItemModel) and have created tree emulation for it. You can take a look into code "here":http://qt-way-notes.blogspot.com/2010/07/tree-model-qml.html , entire blogpost is in Russian, but code is available there too.
-
If the hierarchy isn't too complex, you could try a ListView-within-a-ListView approach -- the delegate of your top-level ListView contains another ListView, which uses a VisualDataModel with a "rootIndex":http://doc.trolltech.com/4.7/qml-visualdatamodel.html#rootIndex-prop specified.