diff --git a/README.md b/README.md index ccd19f1..e556e24 100644 --- a/README.md +++ b/README.md @@ -1,9 +1,7 @@ -# QMLTreeView +# QMLTreeView 1.0 This project provides a **QML Tree View** with a **C++ Tree Model** for **Qt 5.15** and **QuickControls 2**. -The project is still in beta, so breaking change can happen and backward compatibility is still not guaranteed. - ## Features - QML Tree View - C++ Tree Model @@ -22,19 +20,23 @@ The project is still in beta, so breaking change can happen and backward compati ``` int main() { - auto parent1 = new TreeItem("Parent1"); - auto parent2 = new TreeItem("Parent2"); - auto child1 = new TreeItem("Child1"); - auto grandChild1 = new TreeItem("GrandChild1"); - + auto america = new TreeItem("America"); + auto asia = new TreeItem("Asia"); + auto europe = new TreeItem("Europe"); + auto brazil = new TreeItem("Brazil"); + auto canada = new TreeItem("Canada"); + auto italy = new TreeItem("Italy"); + auto portugal = new TreeItem("Portugal"); + auto treeModel = new TreeModel(); - auto root = treeModel->rootItem().get(); - treeModel->addItem(root, parent1); - treeModel->addItem(root, parent2); - treeModel->addItem(parent1, child1); - treeModel->addItem(child1, grandChild1); - treeModel->addItem(child1, grandChild2); - + model.addTopLevelItem(america); + model.addTopLevelItem(asia); + model.addTopLevelItem(europe); + model.addItem(america, brazil); + model.addItem(america, canada); + model.addItem(europe, italy); + model.addItem(europe, portugal); + QQmlApplicationEngine engine; engine.rootContext()->setContextProperty("treeModel", treeModel); engine.load(url); @@ -56,7 +58,7 @@ Expose and populate the TreeModel from C++, then just initialize it ``` and this is the result -![](img/treeview01.png) +![](img/minimal.png) # Platforms @@ -67,6 +69,14 @@ Code has been tested in the following OS: - Windows - Linux +# Installation + +- Copy the ```modules``` folder to your project, then add the ```qmltreeview.pri``` file or manually add headers, source and +resource file. +- Add the modules path to the ```QML_IMPORT_PATH```. +- In the main file add the import path to the engine with ```engine.addImportPath("qrc:/modules");``` +- In the QML file you can include the module with ```import QMLTreeView 1.0``` + # Customization ## Selection / Hovering @@ -82,7 +92,7 @@ Hovering and selection can be activated enabling the respective properties } ``` -![](img/treeview02.png) +![](img/selection.png) ## Styling @@ -109,7 +119,7 @@ TreeView support color styling for each part. Positioning can be customized with } ``` -![](img/treeview03.png) +![](img/styled.png) Font can be customized through properties ```font``` and ```fontMetrics```. @@ -217,7 +227,7 @@ TreeView { } } ``` -![](img/treeview04.png) +![](img/customdelegate.png) ## Data Access @@ -231,7 +241,7 @@ Data access for row element is provided by the properties: ```TreeModel``` provides the methods ```addTopLevelItem,``` ```addItem```, ```removeItem``` and ```clear``` to add and remove node to the tree. ```setData``` instead provides a way to change the data of a given node. Take a look at the **Manipulator Example** which show a way to manipulate the tree directly from QML. -![](img/manipulation.png) +![](img/manipulator.png) ## Customizing Models @@ -296,4 +306,4 @@ TreeView { } ``` -![](img/treeview05.png) +![](img/json.png) diff --git a/examples/customdelegate/main.cpp b/examples/customdelegate/main.cpp index 4d6587d..062d709 100644 --- a/examples/customdelegate/main.cpp +++ b/examples/customdelegate/main.cpp @@ -6,35 +6,33 @@ void populateModel(TreeModel& model) { - auto parent1 = new TreeItem("Parent1"); - auto parent2 = new TreeItem("Parent2"); - auto parent3 = new TreeItem("Parent3"); - auto parent4 = new TreeItem("Parent4"); - auto parent5 = new TreeItem("Parent5"); - auto parent6 = new TreeItem("Parent6"); - - auto child1 = new TreeItem("Child1"); - auto child2 = new TreeItem("Child2"); - auto child3 = new TreeItem("Child3"); - auto grandChild1 = new TreeItem("GrandChild1"); - auto grandChild2 = new TreeItem("GrandChild2"); - auto grateChild1 = new TreeItem("GreateChild1"); - auto grateChild2 = new TreeItem("GreateChild2"); - - model.addTopLevelItem(parent1); - model.addTopLevelItem(parent2); - model.addTopLevelItem(parent3); - model.addTopLevelItem(parent4); - model.addTopLevelItem(parent5); - model.addTopLevelItem(parent6); - - model.addItem(parent1, child1); - model.addItem(parent1, child2); - model.addItem(parent1, child3); - model.addItem(child1, grandChild1); - model.addItem(child1, grandChild2); - model.addItem(grandChild1, grateChild1); - model.addItem(grandChild1, grateChild2); + auto america = new TreeItem("America"); + auto asia = new TreeItem("Asia"); + auto europe = new TreeItem("Europe"); + auto oceania = new TreeItem("Oceania"); + + auto brazil = new TreeItem("Brazil"); + auto canada = new TreeItem("Canada"); + auto mexico = new TreeItem("Mexico"); + auto usa = new TreeItem("USA"); + + auto italy = new TreeItem("Italy"); + auto france = new TreeItem("France"); + auto portugal = new TreeItem("Portugal"); + auto spain = new TreeItem("Spain"); + + model.addTopLevelItem(america); + model.addTopLevelItem(asia); + model.addTopLevelItem(europe); + model.addTopLevelItem(oceania); + model.addItem(america, brazil); + model.addItem(america, canada); + model.addItem(america, mexico); + model.addItem(america, usa); + model.addItem(europe, italy); + model.addItem(europe, france); + model.addItem(europe, portugal); + model.addItem(europe, spain); } int main(int argc, char *argv[]) { diff --git a/examples/customdelegate/main.qml b/examples/customdelegate/main.qml index 09ca3fb..0ecb8da 100644 --- a/examples/customdelegate/main.qml +++ b/examples/customdelegate/main.qml @@ -12,13 +12,7 @@ Window { height: 400 title: qsTr("Custom Delegate") - Rectangle { - anchors.fill: parent - border.width: 1 - border.color: "black" - clip: true - - TreeView { + TreeView { id: delegateTreeView anchors.fill: parent anchors.margins: 1 @@ -89,6 +83,6 @@ Window { onCurrentDataChanged: console.log("current data is " + currentData) onCurrentItemChanged: console.log("current item is " + currentItem) } - } + } diff --git a/examples/minimal/main.cpp b/examples/minimal/main.cpp index 4d6587d..062d709 100644 --- a/examples/minimal/main.cpp +++ b/examples/minimal/main.cpp @@ -6,35 +6,33 @@ void populateModel(TreeModel& model) { - auto parent1 = new TreeItem("Parent1"); - auto parent2 = new TreeItem("Parent2"); - auto parent3 = new TreeItem("Parent3"); - auto parent4 = new TreeItem("Parent4"); - auto parent5 = new TreeItem("Parent5"); - auto parent6 = new TreeItem("Parent6"); - - auto child1 = new TreeItem("Child1"); - auto child2 = new TreeItem("Child2"); - auto child3 = new TreeItem("Child3"); - auto grandChild1 = new TreeItem("GrandChild1"); - auto grandChild2 = new TreeItem("GrandChild2"); - auto grateChild1 = new TreeItem("GreateChild1"); - auto grateChild2 = new TreeItem("GreateChild2"); - - model.addTopLevelItem(parent1); - model.addTopLevelItem(parent2); - model.addTopLevelItem(parent3); - model.addTopLevelItem(parent4); - model.addTopLevelItem(parent5); - model.addTopLevelItem(parent6); - - model.addItem(parent1, child1); - model.addItem(parent1, child2); - model.addItem(parent1, child3); - model.addItem(child1, grandChild1); - model.addItem(child1, grandChild2); - model.addItem(grandChild1, grateChild1); - model.addItem(grandChild1, grateChild2); + auto america = new TreeItem("America"); + auto asia = new TreeItem("Asia"); + auto europe = new TreeItem("Europe"); + auto oceania = new TreeItem("Oceania"); + + auto brazil = new TreeItem("Brazil"); + auto canada = new TreeItem("Canada"); + auto mexico = new TreeItem("Mexico"); + auto usa = new TreeItem("USA"); + + auto italy = new TreeItem("Italy"); + auto france = new TreeItem("France"); + auto portugal = new TreeItem("Portugal"); + auto spain = new TreeItem("Spain"); + + model.addTopLevelItem(america); + model.addTopLevelItem(asia); + model.addTopLevelItem(europe); + model.addTopLevelItem(oceania); + model.addItem(america, brazil); + model.addItem(america, canada); + model.addItem(america, mexico); + model.addItem(america, usa); + model.addItem(europe, italy); + model.addItem(europe, france); + model.addItem(europe, portugal); + model.addItem(europe, spain); } int main(int argc, char *argv[]) { diff --git a/examples/styled/main.cpp b/examples/styled/main.cpp index 4d6587d..062d709 100644 --- a/examples/styled/main.cpp +++ b/examples/styled/main.cpp @@ -6,35 +6,33 @@ void populateModel(TreeModel& model) { - auto parent1 = new TreeItem("Parent1"); - auto parent2 = new TreeItem("Parent2"); - auto parent3 = new TreeItem("Parent3"); - auto parent4 = new TreeItem("Parent4"); - auto parent5 = new TreeItem("Parent5"); - auto parent6 = new TreeItem("Parent6"); - - auto child1 = new TreeItem("Child1"); - auto child2 = new TreeItem("Child2"); - auto child3 = new TreeItem("Child3"); - auto grandChild1 = new TreeItem("GrandChild1"); - auto grandChild2 = new TreeItem("GrandChild2"); - auto grateChild1 = new TreeItem("GreateChild1"); - auto grateChild2 = new TreeItem("GreateChild2"); - - model.addTopLevelItem(parent1); - model.addTopLevelItem(parent2); - model.addTopLevelItem(parent3); - model.addTopLevelItem(parent4); - model.addTopLevelItem(parent5); - model.addTopLevelItem(parent6); - - model.addItem(parent1, child1); - model.addItem(parent1, child2); - model.addItem(parent1, child3); - model.addItem(child1, grandChild1); - model.addItem(child1, grandChild2); - model.addItem(grandChild1, grateChild1); - model.addItem(grandChild1, grateChild2); + auto america = new TreeItem("America"); + auto asia = new TreeItem("Asia"); + auto europe = new TreeItem("Europe"); + auto oceania = new TreeItem("Oceania"); + + auto brazil = new TreeItem("Brazil"); + auto canada = new TreeItem("Canada"); + auto mexico = new TreeItem("Mexico"); + auto usa = new TreeItem("USA"); + + auto italy = new TreeItem("Italy"); + auto france = new TreeItem("France"); + auto portugal = new TreeItem("Portugal"); + auto spain = new TreeItem("Spain"); + + model.addTopLevelItem(america); + model.addTopLevelItem(asia); + model.addTopLevelItem(europe); + model.addTopLevelItem(oceania); + model.addItem(america, brazil); + model.addItem(america, canada); + model.addItem(america, mexico); + model.addItem(america, usa); + model.addItem(europe, italy); + model.addItem(europe, france); + model.addItem(europe, portugal); + model.addItem(europe, spain); } int main(int argc, char *argv[]) { diff --git a/examples/styled/main.qml b/examples/styled/main.qml index c698585..c83be1f 100644 --- a/examples/styled/main.qml +++ b/examples/styled/main.qml @@ -12,36 +12,29 @@ Window { height: 400 title: qsTr("Styled TreeView") - Rectangle { - anchors.fill: parent - border.width: 1 - border.color: "black" - clip: true - - TreeView { - id: styledTreeView - - anchors.fill: parent - anchors.margins: 1 - - model: treeModel - selectionEnabled: true - hoverEnabled: true - - color: "steelblue" - handleColor: "steelblue" - hoverColor: "skyblue" - selectedColor: "cornflowerblue" - selectedItemColor: "white" - handleStyle: TreeView.Handle.Chevron - rowHeight: 40 - rowPadding: 30 - rowSpacing: 12 - font.pixelSize: 20 - - onCurrentIndexChanged: console.log("current index is (row=" + currentIndex.row + ", depth=" + model.depth(currentIndex) + ")") - onCurrentDataChanged: console.log("current data is " + currentData) - onCurrentItemChanged: console.log("current item is " + currentItem) - } - } + TreeView { + id: styledTreeView + + anchors.fill: parent + anchors.margins: 1 + + model: treeModel + selectionEnabled: true + hoverEnabled: true + + color: "steelblue" + handleColor: "steelblue" + hoverColor: "skyblue" + selectedColor: "cornflowerblue" + selectedItemColor: "white" + handleStyle: TreeView.Handle.Chevron + rowHeight: 40 + rowPadding: 30 + rowSpacing: 12 + font.pixelSize: 20 + + onCurrentIndexChanged: console.log("current index is (row=" + currentIndex.row + ", depth=" + model.depth(currentIndex) + ")") + onCurrentDataChanged: console.log("current data is " + currentData) + onCurrentItemChanged: console.log("current item is " + currentItem) + } } diff --git a/img/customdelegate.png b/img/customdelegate.png new file mode 100644 index 0000000..6cc33bd Binary files /dev/null and b/img/customdelegate.png differ diff --git a/img/json.png b/img/json.png new file mode 100644 index 0000000..cc8cc76 Binary files /dev/null and b/img/json.png differ diff --git a/img/manipulation.png b/img/manipulation.png deleted file mode 100644 index b7125d9..0000000 Binary files a/img/manipulation.png and /dev/null differ diff --git a/img/manipulator.png b/img/manipulator.png new file mode 100644 index 0000000..4acb4f8 Binary files /dev/null and b/img/manipulator.png differ diff --git a/img/minimal.png b/img/minimal.png new file mode 100644 index 0000000..ffbe467 Binary files /dev/null and b/img/minimal.png differ diff --git a/img/selection.png b/img/selection.png new file mode 100644 index 0000000..10529e3 Binary files /dev/null and b/img/selection.png differ diff --git a/img/styled.png b/img/styled.png new file mode 100644 index 0000000..305fa49 Binary files /dev/null and b/img/styled.png differ diff --git a/img/treeview01.png b/img/treeview01.png deleted file mode 100644 index baa02d2..0000000 Binary files a/img/treeview01.png and /dev/null differ diff --git a/img/treeview02.png b/img/treeview02.png deleted file mode 100644 index c5c9226..0000000 Binary files a/img/treeview02.png and /dev/null differ diff --git a/img/treeview03.png b/img/treeview03.png deleted file mode 100644 index 718e79c..0000000 Binary files a/img/treeview03.png and /dev/null differ diff --git a/img/treeview04.png b/img/treeview04.png deleted file mode 100644 index f780aed..0000000 Binary files a/img/treeview04.png and /dev/null differ diff --git a/img/treeview05.png b/img/treeview05.png deleted file mode 100644 index cb5a5e0..0000000 Binary files a/img/treeview05.png and /dev/null differ diff --git a/img/treeviewbasic.png b/img/treeviewbasic.png deleted file mode 100644 index 9690650..0000000 Binary files a/img/treeviewbasic.png and /dev/null differ