summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorCarl Schwan <carl@carlschwan.eu>2023-05-26 16:51:49 +0200
committerVolker Hilsheimer <volker.hilsheimer@qt.io>2023-06-28 19:26:45 +0000
commit25027444a9b53d61a6257dc5f5ce0ffdb3b06f98 (patch)
tree9a08a47b66e6c2dbd3a7b3e53deeb8a269a490ae
parentbe1b589cb9f147762a5a73d2b3a44778b7ae7502 (diff)
Modernize SimpleTreeModel example
Use std::unique_ptr to manage items tree memory allocations. This also use the new string literals operator. Change-Id: Iab002b5dc612b75cef0be10862e263c6c6c013c1 Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io>
-rw-r--r--examples/widgets/doc/src/simpletreemodel.qdoc28
-rw-r--r--examples/widgets/itemviews/simpletreemodel/treeitem.cpp52
-rw-r--r--examples/widgets/itemviews/simpletreemodel/treeitem.h9
-rw-r--r--examples/widgets/itemviews/simpletreemodel/treemodel.cpp29
-rw-r--r--examples/widgets/itemviews/simpletreemodel/treemodel.h2
5 files changed, 59 insertions, 61 deletions
diff --git a/examples/widgets/doc/src/simpletreemodel.qdoc b/examples/widgets/doc/src/simpletreemodel.qdoc
index 5892d05244..3ab5a70151 100644
--- a/examples/widgets/doc/src/simpletreemodel.qdoc
+++ b/examples/widgets/doc/src/simpletreemodel.qdoc
@@ -104,16 +104,14 @@
\snippet itemviews/simpletreemodel/treeitem.cpp 0
A pointer to each of the child items belonging to this item will be
- stored in the \c childItems private member variable. When the class's
- destructor is called, it must delete each of these to ensure that
- their memory is reused:
-
- \snippet itemviews/simpletreemodel/treeitem.cpp 1
+ stored in the \c childItems private member variable as an std::unique_ptr.
+ When the class's destructor is called, the child items will be automatically
+ deleted to ensure that their memory is reused:
Since each of the child items are constructed when the model is initially
populated with data, the function to add child items is straightforward:
- \snippet itemviews/simpletreemodel/treeitem.cpp 2
+ \snippet itemviews/simpletreemodel/treeitem.cpp 1
Each item is able to return any of its child items when given a suitable
row number. For example, in the \l{#SimpleTreeModelStructure}{above diagram},
@@ -124,11 +122,11 @@
The \c child() function returns the child that corresponds to
the specified row number in the item's list of child items:
- \snippet itemviews/simpletreemodel/treeitem.cpp 3
+ \snippet itemviews/simpletreemodel/treeitem.cpp 2
The number of child items held can be found with \c childCount():
- \snippet itemviews/simpletreemodel/treeitem.cpp 4
+ \snippet itemviews/simpletreemodel/treeitem.cpp 3
The \c TreeModel uses this function to determine the number of rows that
exist for a given parent item.
@@ -136,7 +134,7 @@
The \c row() function reports the item's location within its parent's
list of items:
- \snippet itemviews/simpletreemodel/treeitem.cpp 8
+ \snippet itemviews/simpletreemodel/treeitem.cpp 7
Note that, although the root item (with no parent item) is automatically
assigned a row number of 0, this information is never used by the model.
@@ -144,16 +142,16 @@
The number of columns of data in the item is trivially returned by the
\c columnCount() function.
- \snippet itemviews/simpletreemodel/treeitem.cpp 5
+ \snippet itemviews/simpletreemodel/treeitem.cpp 4
Column data is returned by the \c data() function. The bounds are checked
before accessing the container with the data:
- \snippet itemviews/simpletreemodel/treeitem.cpp 6
+ \snippet itemviews/simpletreemodel/treeitem.cpp 5
The item's parent is found with \c parent():
- \snippet itemviews/simpletreemodel/treeitem.cpp 7
+ \snippet itemviews/simpletreemodel/treeitem.cpp 6
Note that, since the root item in the model will not have a parent, this
function will return zero in that case. We need to ensure that the model
@@ -183,14 +181,16 @@
item only contains vertical header data for convenience. We also use it
to reference the internal data structure that contains the model data,
and it is used to represent an imaginary parent of top-level items in
- the model.
+ the model. The root item is managed with a std::unique_ptr to ensure the
+ entire tree of item is deleted when the model is deleted.
The model's internal data structure is populated with items by the
\c setupModelData() function. We will examine this function separately
at the end of this document.
The destructor ensures that the root item and all of its descendants
- are deleted when the model is destroyed:
+ are deleted when the model is destroyed. This is done automatically
+ since the root item is stored in a unique_ptr.
\snippet itemviews/simpletreemodel/treemodel.cpp 1
diff --git a/examples/widgets/itemviews/simpletreemodel/treeitem.cpp b/examples/widgets/itemviews/simpletreemodel/treeitem.cpp
index 59292bbbca..611a6a0976 100644
--- a/examples/widgets/itemviews/simpletreemodel/treeitem.cpp
+++ b/examples/widgets/itemviews/simpletreemodel/treeitem.cpp
@@ -10,70 +10,70 @@
#include "treeitem.h"
//! [0]
-TreeItem::TreeItem(const QList<QVariant> &data, TreeItem *parent)
+TreeItem::TreeItem(const QVariantList &data, TreeItem *parent)
: m_itemData(data), m_parentItem(parent)
{}
//! [0]
//! [1]
-TreeItem::~TreeItem()
+void TreeItem::appendChild(std::unique_ptr<TreeItem> &&child)
{
- qDeleteAll(m_childItems);
+ m_childItems.push_back(std::move(child));
}
//! [1]
//! [2]
-void TreeItem::appendChild(TreeItem *item)
-{
- m_childItems.append(item);
-}
-//! [2]
-
-//! [3]
TreeItem *TreeItem::child(int row)
{
if (row < 0 || row >= m_childItems.size())
return nullptr;
- return m_childItems.at(row);
+ return m_childItems.at(row).get();
}
-//! [3]
+//! [2]
-//! [4]
+//! [3]
int TreeItem::childCount() const
{
- return m_childItems.count();
+ return m_childItems.size();
}
-//! [4]
+//! [3]
-//! [5]
+//! [4]
int TreeItem::columnCount() const
{
return m_itemData.count();
}
-//! [5]
+//! [4]
-//! [6]
+//! [5]
QVariant TreeItem::data(int column) const
{
if (column < 0 || column >= m_itemData.size())
return QVariant();
return m_itemData.at(column);
}
-//! [6]
+//! [5]
-//! [7]
+//! [6]
TreeItem *TreeItem::parentItem()
{
return m_parentItem;
}
-//! [7]
+//! [6]
-//! [8]
+//! [7]
int TreeItem::row() const
{
- if (m_parentItem)
- return m_parentItem->m_childItems.indexOf(const_cast<TreeItem*>(this));
+ if (!m_parentItem)
+ return 0;
+ const auto it = std::find_if(m_parentItem->m_childItems.cbegin(), m_parentItem->m_childItems.cend(),
+ [this](const std::unique_ptr<TreeItem> &treeItem) {
+ return treeItem.get() == const_cast<TreeItem *>(this);
+ });
- return 0;
+ if (it != m_parentItem->m_childItems.cend())
+ return std::distance(m_parentItem->m_childItems.cbegin(), it);
+ Q_ASSERT(false); // should not happen
+ return -1;
}
-//! [8]
+//! [7]
diff --git a/examples/widgets/itemviews/simpletreemodel/treeitem.h b/examples/widgets/itemviews/simpletreemodel/treeitem.h
index b2508b9058..8edebcc34b 100644
--- a/examples/widgets/itemviews/simpletreemodel/treeitem.h
+++ b/examples/widgets/itemviews/simpletreemodel/treeitem.h
@@ -11,10 +11,9 @@
class TreeItem
{
public:
- explicit TreeItem(const QList<QVariant> &data, TreeItem *parentItem = nullptr);
- ~TreeItem();
+ explicit TreeItem(const QVariantList &data, TreeItem *parentItem = nullptr);
- void appendChild(TreeItem *child);
+ void appendChild(std::unique_ptr<TreeItem> &&child);
TreeItem *child(int row);
int childCount() const;
@@ -24,8 +23,8 @@ public:
TreeItem *parentItem();
private:
- QList<TreeItem *> m_childItems;
- QList<QVariant> m_itemData;
+ std::vector<std::unique_ptr<TreeItem>> m_childItems;
+ QVariantList m_itemData;
TreeItem *m_parentItem;
};
//! [0]
diff --git a/examples/widgets/itemviews/simpletreemodel/treemodel.cpp b/examples/widgets/itemviews/simpletreemodel/treemodel.cpp
index 1665f18ebe..93cd6709a9 100644
--- a/examples/widgets/itemviews/simpletreemodel/treemodel.cpp
+++ b/examples/widgets/itemviews/simpletreemodel/treemodel.cpp
@@ -13,20 +13,19 @@
#include <QStringList>
+using namespace Qt::StringLiterals;
+
//! [0]
TreeModel::TreeModel(const QString &data, QObject *parent)
: QAbstractItemModel(parent)
+ , rootItem(std::make_unique<TreeItem>(QVariantList{tr("Title"), tr("Summary")}))
{
- rootItem = new TreeItem({tr("Title"), tr("Summary")});
- setupModelData(data.split('\n'), rootItem);
+ setupModelData(data.split('\n'_L1), rootItem.get());
}
//! [0]
//! [1]
-TreeModel::~TreeModel()
-{
- delete rootItem;
-}
+TreeModel::~TreeModel() = default;
//! [1]
//! [2]
@@ -47,7 +46,7 @@ QVariant TreeModel::data(const QModelIndex &index, int role) const
if (role != Qt::DisplayRole)
return QVariant();
- TreeItem *item = static_cast<TreeItem*>(index.internalPointer());
+ auto item = static_cast<TreeItem*>(index.internalPointer());
return item->data(index.column());
}
@@ -83,11 +82,11 @@ QModelIndex TreeModel::index(int row, int column, const QModelIndex &parent) con
TreeItem *parentItem;
if (!parent.isValid())
- parentItem = rootItem;
+ parentItem = rootItem.get();
else
parentItem = static_cast<TreeItem*>(parent.internalPointer());
- TreeItem *childItem = parentItem->child(row);
+ auto childItem = parentItem->child(row);
if (childItem)
return createIndex(row, column, childItem);
return QModelIndex();
@@ -103,7 +102,7 @@ QModelIndex TreeModel::parent(const QModelIndex &index) const
TreeItem *childItem = static_cast<TreeItem*>(index.internalPointer());
TreeItem *parentItem = childItem->parentItem();
- if (parentItem == rootItem)
+ if (parentItem == rootItem.get())
return QModelIndex();
return createIndex(parentItem->row(), 0, parentItem);
@@ -118,7 +117,7 @@ int TreeModel::rowCount(const QModelIndex &parent) const
return 0;
if (!parent.isValid())
- parentItem = rootItem;
+ parentItem = rootItem.get();
else
parentItem = static_cast<TreeItem*>(parent.internalPointer());
@@ -138,7 +137,7 @@ void TreeModel::setupModelData(const QStringList &lines, TreeItem *parent)
while (number < lines.count()) {
int position = 0;
while (position < lines[number].length()) {
- if (lines[number].at(position) != ' ')
+ if (lines[number].at(position) != ' '_L1)
break;
position++;
}
@@ -148,8 +147,8 @@ void TreeModel::setupModelData(const QStringList &lines, TreeItem *parent)
if (!lineData.isEmpty()) {
// Read the column data from the rest of the line.
const QStringList columnStrings =
- lineData.split(QLatin1Char('\t'), Qt::SkipEmptyParts);
- QList<QVariant> columnData;
+ lineData.split('\t'_L1, Qt::SkipEmptyParts);
+ QVariantList columnData;
columnData.reserve(columnStrings.count());
for (const QString &columnString : columnStrings)
columnData << columnString;
@@ -170,7 +169,7 @@ void TreeModel::setupModelData(const QStringList &lines, TreeItem *parent)
}
// Append a new item to the current parent's list of children.
- parents.last()->appendChild(new TreeItem(columnData, parents.last()));
+ parents.last()->appendChild(std::make_unique<TreeItem>(columnData, parents.last()));
}
++number;
}
diff --git a/examples/widgets/itemviews/simpletreemodel/treemodel.h b/examples/widgets/itemviews/simpletreemodel/treemodel.h
index aa93c33494..0a771088ed 100644
--- a/examples/widgets/itemviews/simpletreemodel/treemodel.h
+++ b/examples/widgets/itemviews/simpletreemodel/treemodel.h
@@ -32,7 +32,7 @@ public:
private:
void setupModelData(const QStringList &lines, TreeItem *parent);
- TreeItem *rootItem;
+ std::unique_ptr<TreeItem> rootItem;
};
//! [0]