Polish the SimpleTreeModel example

- Fix/silence most clang-tidy/compiler warnings
  * unsigned/int comparison
  * Avoid repeating return / default parameter types
  * Make functions static/use static invocations
  * Use string literals everywhere
  * Use auto * for pointers
  * Streamline code, use ternary operators
  * Move constructor parameters
  * Observe rule of 5 by using Q_DISABLE_COPY_MOVE
- Add some bells && whistles, resize properly, expand all

Complements 25027444a9b53d61a6257dc5f5ce0ffdb3b06f98.

Change-Id: I78f48d187981ecabf69a5d4d42715bad026fa9e6
Reviewed-by: Kai Köhne <kai.koehne@qt.io>
(cherry picked from commit a3e20df03d522bd1b07ac7a85578401f36f290b9)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
This commit is contained in:
Friedemann Kleint 2023-11-15 21:57:42 +01:00 committed by Qt Cherry-pick Bot
parent 5c8e47d2dd
commit e19f344460
6 changed files with 52 additions and 61 deletions

View File

@ -145,8 +145,9 @@
\snippet itemviews/simpletreemodel/treeitem.cpp 4 \snippet itemviews/simpletreemodel/treeitem.cpp 4
Column data is returned by the \c data() function. The bounds are checked Column data is returned by the \c data() function. We use
before accessing the container with the data: the QList::value() convenience function which checks the bounds
and returns a default-constructed QVariant in case they are violated:
\snippet itemviews/simpletreemodel/treeitem.cpp 5 \snippet itemviews/simpletreemodel/treeitem.cpp 5

View File

@ -5,20 +5,28 @@
#include <QApplication> #include <QApplication>
#include <QFile> #include <QFile>
#include <QScreen>
#include <QTreeView> #include <QTreeView>
using namespace Qt::StringLiterals;
int main(int argc, char *argv[]) int main(int argc, char *argv[])
{ {
QApplication app(argc, argv); QApplication app(argc, argv);
QFile file(":/default.txt"); QFile file(":/default.txt"_L1);
file.open(QIODevice::ReadOnly); file.open(QIODevice::ReadOnly | QIODevice::Text);
TreeModel model(file.readAll()); TreeModel model(QString::fromUtf8(file.readAll()));
file.close(); file.close();
QTreeView view; QTreeView view;
view.setModel(&model); view.setModel(&model);
view.setWindowTitle(QObject::tr("Simple Tree Model")); view.setWindowTitle(TreeModel::tr("Simple Tree Model"));
for (int c = 0; c < model.columnCount(); ++c)
view.resizeColumnToContents(c);
view.expandAll();
const auto screenSize = view.screen()->availableSize();
view.resize({screenSize.width() / 2, screenSize.height() * 2 / 3});
view.show(); view.show();
return app.exec(); return QCoreApplication::exec();
} }

View File

@ -10,8 +10,8 @@
#include "treeitem.h" #include "treeitem.h"
//! [0] //! [0]
TreeItem::TreeItem(const QVariantList &data, TreeItem *parent) TreeItem::TreeItem(QVariantList data, TreeItem *parent)
: m_itemData(data), m_parentItem(parent) : m_itemData(std::move(data)), m_parentItem(parent)
{} {}
//! [0] //! [0]
@ -25,32 +25,28 @@ void TreeItem::appendChild(std::unique_ptr<TreeItem> &&child)
//! [2] //! [2]
TreeItem *TreeItem::child(int row) TreeItem *TreeItem::child(int row)
{ {
if (row < 0 || row >= m_childItems.size()) return row >= 0 && row < childCount() ? m_childItems.at(row).get() : nullptr;
return nullptr;
return m_childItems.at(row).get();
} }
//! [2] //! [2]
//! [3] //! [3]
int TreeItem::childCount() const int TreeItem::childCount() const
{ {
return m_childItems.size(); return int(m_childItems.size());
} }
//! [3] //! [3]
//! [4] //! [4]
int TreeItem::columnCount() const int TreeItem::columnCount() const
{ {
return m_itemData.count(); return int(m_itemData.count());
} }
//! [4] //! [4]
//! [5] //! [5]
QVariant TreeItem::data(int column) const QVariant TreeItem::data(int column) const
{ {
if (column < 0 || column >= m_itemData.size()) return m_itemData.value(column);
return QVariant();
return m_itemData.at(column);
} }
//! [5] //! [5]
@ -64,11 +60,11 @@ TreeItem *TreeItem::parentItem()
//! [7] //! [7]
int TreeItem::row() const int TreeItem::row() const
{ {
if (!m_parentItem) if (m_parentItem == nullptr)
return 0; return 0;
const auto it = std::find_if(m_parentItem->m_childItems.cbegin(), m_parentItem->m_childItems.cend(), const auto it = std::find_if(m_parentItem->m_childItems.cbegin(), m_parentItem->m_childItems.cend(),
[this](const std::unique_ptr<TreeItem> &treeItem) { [this](const std::unique_ptr<TreeItem> &treeItem) {
return treeItem.get() == const_cast<TreeItem *>(this); return treeItem.get() == this;
}); });
if (it != m_parentItem->m_childItems.cend()) if (it != m_parentItem->m_childItems.cend())

View File

@ -11,7 +11,7 @@
class TreeItem class TreeItem
{ {
public: public:
explicit TreeItem(const QVariantList &data, TreeItem *parentItem = nullptr); explicit TreeItem(QVariantList data, TreeItem *parentItem = nullptr);
void appendChild(std::unique_ptr<TreeItem> &&child); void appendChild(std::unique_ptr<TreeItem> &&child);

View File

@ -40,14 +40,10 @@ int TreeModel::columnCount(const QModelIndex &parent) const
//! [3] //! [3]
QVariant TreeModel::data(const QModelIndex &index, int role) const QVariant TreeModel::data(const QModelIndex &index, int role) const
{ {
if (!index.isValid()) if (!index.isValid() || role != Qt::DisplayRole)
return QVariant(); return {};
if (role != Qt::DisplayRole)
return QVariant();
auto item = static_cast<TreeItem*>(index.internalPointer());
const auto *item = static_cast<const TreeItem*>(index.internalPointer());
return item->data(index.column()); return item->data(index.column());
} }
//! [3] //! [3]
@ -55,10 +51,8 @@ QVariant TreeModel::data(const QModelIndex &index, int role) const
//! [4] //! [4]
Qt::ItemFlags TreeModel::flags(const QModelIndex &index) const Qt::ItemFlags TreeModel::flags(const QModelIndex &index) const
{ {
if (!index.isValid()) return index.isValid()
return Qt::NoItemFlags; ? QAbstractItemModel::flags(index) : Qt::ItemFlags(Qt::NoItemFlags);
return QAbstractItemModel::flags(index);
} }
//! [4] //! [4]
@ -66,10 +60,8 @@ Qt::ItemFlags TreeModel::flags(const QModelIndex &index) const
QVariant TreeModel::headerData(int section, Qt::Orientation orientation, QVariant TreeModel::headerData(int section, Qt::Orientation orientation,
int role) const int role) const
{ {
if (orientation == Qt::Horizontal && role == Qt::DisplayRole) return orientation == Qt::Horizontal && role == Qt::DisplayRole
return rootItem->data(section); ? rootItem->data(section) : QVariant{};
return QVariant();
} }
//! [5] //! [5]
@ -77,19 +69,15 @@ QVariant TreeModel::headerData(int section, Qt::Orientation orientation,
QModelIndex TreeModel::index(int row, int column, const QModelIndex &parent) const QModelIndex TreeModel::index(int row, int column, const QModelIndex &parent) const
{ {
if (!hasIndex(row, column, parent)) if (!hasIndex(row, column, parent))
return QModelIndex(); return {};
TreeItem *parentItem; TreeItem *parentItem = parent.isValid()
? static_cast<TreeItem*>(parent.internalPointer())
: rootItem.get();
if (!parent.isValid()) if (auto *childItem = parentItem->child(row))
parentItem = rootItem.get();
else
parentItem = static_cast<TreeItem*>(parent.internalPointer());
auto childItem = parentItem->child(row);
if (childItem)
return createIndex(row, column, childItem); return createIndex(row, column, childItem);
return QModelIndex(); return {};
} }
//! [6] //! [6]
@ -97,29 +85,25 @@ QModelIndex TreeModel::index(int row, int column, const QModelIndex &parent) con
QModelIndex TreeModel::parent(const QModelIndex &index) const QModelIndex TreeModel::parent(const QModelIndex &index) const
{ {
if (!index.isValid()) if (!index.isValid())
return QModelIndex(); return {};
TreeItem *childItem = static_cast<TreeItem*>(index.internalPointer()); auto *childItem = static_cast<TreeItem*>(index.internalPointer());
TreeItem *parentItem = childItem->parentItem(); TreeItem *parentItem = childItem->parentItem();
if (parentItem == rootItem.get()) return parentItem != rootItem.get()
return QModelIndex(); ? createIndex(parentItem->row(), 0, parentItem) : QModelIndex{};
return createIndex(parentItem->row(), 0, parentItem);
} }
//! [7] //! [7]
//! [8] //! [8]
int TreeModel::rowCount(const QModelIndex &parent) const int TreeModel::rowCount(const QModelIndex &parent) const
{ {
TreeItem *parentItem;
if (parent.column() > 0) if (parent.column() > 0)
return 0; return 0;
if (!parent.isValid()) const TreeItem *parentItem = parent.isValid()
parentItem = rootItem.get(); ? static_cast<const TreeItem*>(parent.internalPointer())
else : rootItem.get();
parentItem = static_cast<TreeItem*>(parent.internalPointer());
return parentItem->childCount(); return parentItem->childCount();
} }

View File

@ -16,21 +16,23 @@ class TreeModel : public QAbstractItemModel
Q_OBJECT Q_OBJECT
public: public:
Q_DISABLE_COPY_MOVE(TreeModel)
explicit TreeModel(const QString &data, QObject *parent = nullptr); explicit TreeModel(const QString &data, QObject *parent = nullptr);
~TreeModel(); ~TreeModel() override;
QVariant data(const QModelIndex &index, int role) const override; QVariant data(const QModelIndex &index, int role) const override;
Qt::ItemFlags flags(const QModelIndex &index) const override; Qt::ItemFlags flags(const QModelIndex &index) const override;
QVariant headerData(int section, Qt::Orientation orientation, QVariant headerData(int section, Qt::Orientation orientation,
int role = Qt::DisplayRole) const override; int role = Qt::DisplayRole) const override;
QModelIndex index(int row, int column, QModelIndex index(int row, int column,
const QModelIndex &parent = QModelIndex()) const override; const QModelIndex &parent = {}) const override;
QModelIndex parent(const QModelIndex &index) const override; QModelIndex parent(const QModelIndex &index) const override;
int rowCount(const QModelIndex &parent = QModelIndex()) const override; int rowCount(const QModelIndex &parent = {}) const override;
int columnCount(const QModelIndex &parent = QModelIndex()) const override; int columnCount(const QModelIndex &parent = {}) const override;
private: private:
void setupModelData(const QStringList &lines, TreeItem *parent); static void setupModelData(const QStringList &lines, TreeItem *parent);
std::unique_ptr<TreeItem> rootItem; std::unique_ptr<TreeItem> rootItem;
}; };