简介
最近遇到一些需求,要在Qt/Qml中开发树结构,并能够导入、导出json格式。
于是我写了一个简易的Demo,并做了一些性能测试。
在这里将源码、实现原理、以及性能测试都记录、分享出来,算是抛砖引玉吧,希望有更多人来讨论、交流。
源码
先放源码
github https://github.com/jaredtao/TreeEdit
gitee https://gitee.com/jaredtao/TreeEdit
效果预览
Qml实现的树结构编辑器, 功能包括:
树结构的缩进
节点展开、折叠
添加节点
删除节点
重命名节点
搜索
导入
导出
节点属性编辑(完善中)
原理说明
数据model的实现,使用C++,继承于QAbstractListModel,并实现rowCount、data等方法。
model本身是List结构的,在此基础上,对model数据进行扩展以模拟树结构,例如增加了 “节点深度”、“是否有子节点”等数据段。
view使用Qml Controls 2中的ListView模拟实现(Controls 1 中的TreeView即将被废弃)。
关键代码
model
基本model的声明如下:
template <typename T>
class TaoListModel : public QAbstractListModel {
public:
//声明父类 using Super = QAbstractListModel;
TaoListModel(QObject* parent = nullptr);
TaoListModel(const QList<T>& nodeList, QObject* parent = nullptr);
const QList<T>& nodeList() const
{
return m_nodeList;
}
void setNodeList(const QList<T>& nodeList);
int rowCount(const QModelIndex& parent) const override;
QVariant data(const QModelIndex& index, int role) const override;
bool setData(const QModelIndex& index, const QVariant& value, int role) override;
bool insertRows(int row, int count, const QModelIndex& parent = QModelIndex()) override;
bool removeRows(int row, int count, const QModelIndex& parent = QModelIndex()) override;
Qt::ItemFlags flags(const QModelIndex& index) const override;
Qt::DropActions supportedDropActions() const override;
protected:
QList<T> m_nodeList;
};
其中数据成员使用 QList m_nodeList 存储, 大部分成员函数是对此数据的操作。
Json格式的model声明如下:
const static QString cDepthKey = QStringLiteral("TModel_depth");
const static QString cExpendKey = QStringLiteral("TModel_expend");
const static QString cChildrenExpendKey = QStringLiteral("TModel_childrenExpend");
const static QString cHasChildendK