搜索
首页php教程php手册使用C++实现QML的TreeView Model (二)

使用C++实现QML的TreeView Model (二)

上文已经介绍过二维表模型的实现方式,接着分享层次模型的实现,首先实现一个节点类用于保存树状数据模型的节点数据和节点关系:

<ol style="margin:0 1px 0 0px;padding-left:40px;" start="1" class="dp-css"><li>class TreeNode;<br /> </li><li><br /></li><li>typedef TreeNode* TreeNodePtr;<br /></li><li><br /></li><li>class TreeNode<br /></li><li>{<br /></li><li>public:<br /></li><li>explicit TreeNode();<br /></li><li>TreeNodePtr parent() const;<br /></li><li>void setParent(const TreeNodePtr p); //设置父节点,根节点的父节点为NULL<br /></li><li>void appendNode(TreeNodePtr node);<br /></li><li>void removeNode(int row);<br /></li><li>void setData(int role,QVariant value);  </li><li>QList<TreeNodePtr>childs;  //用于保存子节点指针,把childs放到public不好,仅仅是为了方便,不要学。<br /></li><li><br /></li><li>private:<br /></li><li>TreeNodePtr mParent=NULL;  //父节点<br /></li><li>QHash<int,QVariant>mRecord; //一个节点可以保存一行数据,哈希表的key是整型,用于保存role,QVariant保存数据<br /></li><li><br /></li><li>}; </li></ol>
TreeNode的实现也是相当简单:

<ol style="margin:0 1px 0 0px;padding-left:40px;" start="1" class="dp-css"><li>TreeNodePtr TreeNode::parent() const<br /> </li><li>{<br /></li><li>return mParent;<br /></li><li>}<br /></li><li><br /></li><li>void TreeNode::setParent(const TreeNodePtr p)<br /></li><li>{<br /></li><li>this->mParent = p;<br /></li><li>}<br /></li><li><br /></li><li>void TreeNode::appendNode(TreeNodePtr node)<br /></li><li>{<br /></li><li>childs.append(node);<br /></li><li>}<br /></li><li><br /></li><li>void TreeNode::removeNode(int row)<br /></li><li>{<br /></li><li>childs.removeAt(row);<br /></li><li>}<br /></li><li><br /></li><li><br /></li><li>QVariant TreeNode::data(int role)<br /></li><li>{<br /></li><li>return mRecord[role];<br /></li><li>}<br /></li><li><br /></li><li>void TreeNode::setData(int role, QVariant value)<br /></li><li>{<br /></li><li>mRecord[role] = value;<br /></li><li>} </li></ol>
接下来开始对SqlMenuEntryModel进行手术:

<ol style="margin:0 1px 0 0px;padding-left:40px;" start="1" class="dp-css"><li>class SqlMenuEntry:public QAbstractItemModel,public QQmlParserStatus<br /> </li><li>{<br /></li><li>Q_OBJECT<br /></li><li>public:<br /></li><li>explicit SqlMenuEntry(QObject *parent=0);<br /></li><li>~SqlMenuEntry();<br /></li><li>enum MenuEntryRoles{idRole=Qt::UserRole+1,nameRole,defaultEntryRole,customEntryRole,iconRole,iconHoverRole};<br /></li><li>int rowCount(const QModelIndex &parent=QModelIndex()) const;<br /></li><li>int columnCount(const QModelIndex &parent=QModelIndex()) const;<br /></li><li>QModelIndex index(int row, int column, const QModelIndex &parent=QModelIndex()) const;<br /></li><li>QVariant data(const QModelIndex &index, int role=Qt::DisplayRole) const;<br /></li><li>QModelIndex parent(const QModelIndex &child) const;<br /></li><li>QHash<int,QByteArray>roleNames() const;<br /></li><li>private:<br /></li><li>QHash<int,QByteArray> mRoleNames;<br /></li><li>  <s>QList</s><s><</s><s>QHash</s><s><</s><s>int</s><s>,</s><s>QVariant</s><s>></s><s>></s><s> mRecords</s><s>;</s> //QList不能保存树状数据,干掉<br /></li><li>  QList mRootEntrys;   //用于保存根节点 </li><li>  void _addEntryNode(TreeNodePtr node,TreeNodePtr parent=0); //用于向树添加节点 </li><li>}; </li></ol>
_addEntryNode的实现如下:

<ol style="margin:0 1px 0 0px;padding-left:40px;" start="1" class="dp-css"><li>void SqlMenuEntry::_addEntryNode(TreeNodePtr node, TreeNodePtr parent)<br /> </li><li>{<br /></li><li>if(parent == NULL)<br /></li><li>{<br /></li><li>mRootEntrys.append(node);<br /></li><li>}else{<br /></li><li>node->setParent(parent);<br /></li><li>parent->appendNode(node);<br /></li><li>}<br /></li><li>} </li><li><br /> </li></ol>
可以通过如下代码向模型添加数据:


<ol style="margin:0 1px 0 0px;padding-left:40px;" start="1" class="dp-css"><li>beginResetModel();<br /> </li><li><br /></li><li>auto node = new TreeNode(); </li><li>node->setData(nameRole,"parent 1");<br /></li><li>node->setData(iconRole,"parenticon1"); </li><li>_addEntryNode(node);  //添加第一个根节点<br /></li><li>    </li><li>     auto subNode = new TreeNode(); </li><li>     subNode->setData(nameRole,"child1");<br /></li><li>     _addEntryNode(subNode,node); //添加子节点 </li><li><br /> </li><li>endResetModel(); </li></ol>
上面的代码向模型添加了一个根节点parent1和parent1的一个子节点child1,接下来可以对SqlMenuEntryModel进行持续改进,让TreeView可以顺利显示正确的数据和数据关系。首先,更改int rowCount(const QModelIndex &parent)让模型可以正确的返回根节点数和子节点行数:

<ol style="margin:0 1px 0 0px;padding-left:40px;" start="1" class="dp-css"><li>int SqlMenuEntry::rowCount(const QModelIndex &parent) const<br /> </li><li>{<br /></li><li>if(parent.isValid()) //parent不为空,则要获取的行数是某个节点的子节点行数<br /></li><li>{<br /></li><li>TreeNodePtr parentNode = (TreeNodePtr)parent.internalPointer(); //节点信息在index时被保存在QModelIndex的internalPointer中<br /></li><li>return parentNode->childs.size();<br /></li><li>} </li><li>return mRootEntrys.size(); //否则返回的是根节点行数<br /></li><li><br /></li><li>} </li></ol>


实现index接口函数,让模型可以返回子节点的modelIndex同时将对应的节点指针保存在modelIndex的internalPointer中:

<ol style="margin:0 1px 0 0px;padding-left:40px;" start="1" class="dp-css"><li>QModelIndex SqlMenuEntry::index(int row, int column, const QModelIndex &parent) const<br /> </li><li>{<br /></li><li>if(!parent.isValid()) //parent为空,返回的是根节点的modelIndex,返回的同时,把节点数据指针(TreeNodePtr)保存在QModelIndex的internalPointer中,以便在其它函数中获取节点数据<br /></li><li>{<br /></li><li>if((row >= 0) && (row < mRootEntrys.size()))<br /></li><li>{<br /></li><li>return createIndex(row,column,mRootEntrys.at(row)); <br /></li><li>}<br /></li><li>}else{<br /></li><li>TreeNodePtr parentNode = (TreeNodePtr)parent.internalPointer(); //返回子节点的modelIndex<br /></li><li>return createIndex(row,column,parentNode->childs[row]);<br /></li><li>}<br /></li><li>return QModelIndex();<br /></li><li>} </li></ol>
parent(const QModelIndex &child) 用于返回一个节点的父节点索引:

<ol style="margin:0 1px 0 0px;padding-left:40px;" start="1" class="dp-css"><li>QModelIndex SqlMenuEntry::parent(const QModelIndex &child) const<br /> </li><li>{<br /></li><li>TreeNodePtr node = (TreeNodePtr)child.internalPointer();<br /></li><li>if(node->parent() == NULL)<br /></li><li>{<br /></li><li>return QModelIndex(); //根节点没有parent<br /></li><li>}else{<br /></li><li>return createIndex(0,1,node->parent());<br /></li><li>} </li></ol>
实现data(constQModelIndex&index,introle) 返回节点中的数据:
<ol style="margin:0 1px 0 0px;padding-left:40px;" start="1" class="dp-css"><li>QVariant SqlMenuEntry::data(const QModelIndex &index, int role) const<br /> </li><li>{<br /></li><li>TreeNodePtr node = (TreeNodePtr)index.internalPointer();<br /></li><li>return node->data(role);<br /></li><li>} </li></ol>

经过上面的打造,模型已经可以正常为TreeView提供数据:

<ol style="margin:0 1px 0 0px;padding-left:40px;" start="1" class="dp-css"><li>TreeView{<br /> </li><li>anchors.fill: parent<br /></li><li>TableViewColumn {<br /></li><li>title: "Name"<br /></li><li>role: "name"<br /></li><li>}<br /></li><li><br /></li><li>TableViewColumn {<br /></li><li>title: "Entry"<br /></li><li>role: "icon"<br /></li><li>}<br /></li><li>model:MenuEntryModel{}<br /></li><li>} </li></ol>
继续干活去了,明天再继续补充数据添加、删除和更新的相关经验。







声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

热AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover

AI Clothes Remover

用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool

Undress AI Tool

免费脱衣服图片

Clothoff.io

Clothoff.io

AI脱衣机

AI Hentai Generator

AI Hentai Generator

免费生成ai无尽的。

热工具

MinGW - 适用于 Windows 的极简 GNU

MinGW - 适用于 Windows 的极简 GNU

这个项目正在迁移到osdn.net/projects/mingw的过程中,你可以继续在那里关注我们。MinGW:GNU编译器集合(GCC)的本地Windows移植版本,可自由分发的导入库和用于构建本地Windows应用程序的头文件;包括对MSVC运行时的扩展,以支持C99功能。MinGW的所有软件都可以在64位Windows平台上运行。

适用于 Eclipse 的 SAP NetWeaver 服务器适配器

适用于 Eclipse 的 SAP NetWeaver 服务器适配器

将Eclipse与SAP NetWeaver应用服务器集成。

Dreamweaver Mac版

Dreamweaver Mac版

视觉化网页开发工具

EditPlus 中文破解版

EditPlus 中文破解版

体积小,语法高亮,不支持代码提示功能

安全考试浏览器

安全考试浏览器

Safe Exam Browser是一个安全的浏览器环境,用于安全地进行在线考试。该软件将任何计算机变成一个安全的工作站。它控制对任何实用工具的访问,并防止学生使用未经授权的资源。