• linkedu视频
  • 平面设计
  • 电脑入门
  • 操作系统
  • 办公应用
  • 电脑硬件
  • 动画设计
  • 3D设计
  • 网页设计
  • CAD设计
  • 影音处理
  • 数据库
  • 程序设计
  • 认证考试
  • 信息管理
  • 信息安全
菜单
linkedu.com
  • 网页制作
  • 数据库
  • 程序设计
  • 操作系统
  • CMS教程
  • 游戏攻略
  • 脚本语言
  • 平面设计
  • 软件教程
  • 网络安全
  • 电脑知识
  • 服务器
  • 视频教程
  • JavaScript
  • ASP.NET
  • PHP
  • 正则表达式
  • AJAX
  • JSP
  • ASP
  • Flex
  • XML
  • 编程技巧
  • Android
  • swift
  • C#教程
  • vb
  • vb.net
  • C语言
  • Java
  • Delphi
  • 易语言
  • vc/mfc
  • 嵌入式开发
  • 游戏开发
  • ios
  • 编程问答
  • 汇编语言
  • 微信小程序
  • 数据结构
  • OpenGL
  • 架构设计
  • qt
  • 微信公众号
您的位置:首页 > 程序设计 >Android > 使用C++实现QML的TreeView Model (二)

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

作者:网友 字体:[增加 减小] 来源:互联网 时间:2017-05-26

网友通过本文主要向大家介绍了qml treeview,qml treeviewstyle,qml model,qml listmodel,qml 绕圈旋转实现等相关知识,希望对您有所帮助,也希望大家支持linkedu.com www.linkedu.com

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


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

  1. class TreeNode;

  2. typedef TreeNode* TreeNodePtr;

  3. class TreeNode
  4. {
  5. public:
  6. explicit TreeNode();
  7. TreeNodePtr parent() const;
  8. void setParent(const TreeNodePtr p); //设置父节点,根节点的父节点为NULL
  9. void appendNode(TreeNodePtr node);
  10. void removeNode(int row);
  11. void setData(int role,QVariant value);
  12. QListchilds; //用于保存子节点指针,把childs放到public不好,仅仅是为了方便,不要学。

  13. private:
  14. TreeNodePtr mParent=NULL; //父节点
  15. QHashmRecord; //一个节点可以保存一行数据,哈希表的key是整型,用于保存role,QVariant保存数据

  16. };
TreeNode的实现也是相当简单:

  1. TreeNodePtr TreeNode::parent() const
  2. {
  3. return mParent;
  4. }

  5. void TreeNode::setParent(const TreeNodePtr p)
  6. {
  7. this->mParent = p;
  8. }

  9. void TreeNode::appendNode(TreeNodePtr node)
  10. {
  11. childs.append(node);
  12. }

  13. void TreeNode::removeNode(int row)
  14. {
  15. childs.removeAt(row);
  16. }


  17. QVariant TreeNode::data(int role)
  18. {
  19. return mRecord[role];
  20. }

  21. void TreeNode::setData(int role, QVariant value)
  22. {
  23. mRecord[role] = value;
  24. }
接下来开始对SqlMenuEntryModel进行手术:

  1. class SqlMenuEntry:public QAbstractItemModel,public QQmlParserStatus
  2. {
  3. Q_OBJECT
  4. public:
  5. explicit SqlMenuEntry(QObject *parent=0);
  6. ~SqlMenuEntry();
  7. enum MenuEntryRoles{idRole=Qt::UserRole+1,nameRole,defaultEntryRole,customEntryRole,iconRole,iconHoverRole};
  8. int rowCount(const QModelIndex &parent=QModelIndex()) const;
  9. int columnCount(const QModelIndex &parent=QModelIndex()) const;
  10. QModelIndex index(int row, int column, const QModelIndex &parent=QModelIndex()) const;
  11. QVariant data(const QModelIndex &index, int role=Qt::DisplayRole) const;
  12. QModelIndex parent(const QModelIndex &child) const;
  13. QHashroleNames() const;
  14. private:
  15. QHash mRoleNames;
  16. QList<QHash<int,QVariant>> mRecords; //QList不能保存树状数据,干掉
  17. QList mRootEntrys; //用于保存根节点
  18. void _addEntryNode(TreeNodePtr node,TreeNodePtr parent=0); //用于向树添加节点
  19. };
_addEntryNode的实现如下:

  1. void SqlMenuEntry::_addEntryNode(TreeNodePtr node, TreeNodePtr parent)
  2. {
  3. if(parent == NULL)
  4. {
  5. mRootEntrys.append(node);
  6. }else{
  7. node->setParent(parent);
  8. parent->appendNode(node);
  9. }
  10. }

可以通过如下代码向模型添加数据:


  1. beginResetModel();

  2. auto node = new TreeNode();
  3. node->setData(nameRole,"parent 1");
  4. node->setData(iconRole,"parenticon1");
  5. _addEntryNode(node); //添加第一个根节点
  6. auto subNode = new TreeNode();
  7. subNode->setData(nameRole,"child1");
  8. _addEntryNode(subNode,node); //添加子节点

  9. endResetModel();
上面的代码向模型添加了一个根节点parent1和parent1的一个子节点child1,接下来可以对SqlMenuEntryModel进行持续改进,让TreeView可以顺利显示正确的数据和数据关系。首先,更改int rowCount(const QModelIndex &parent)让模型可以正确的返回根节点数和子节点行数:

  1. int SqlMenuEntry::rowCount(const QModelIndex &parent) const
  2. {
  3. if(parent.isValid()) //parent不为空,则要获取的行数是某个节点的子节点行数
  4. {
  5. TreeNodePtr parentNode = (TreeNodePtr)parent.internalPointer(); //节点信息在index时被保存在QModelIndex的internalPointer中
  6. return parentNode->childs.size();
  7. }
  8. return mRootEntrys.size(); //否则返回的是根节点行数

  9. }


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

  1. QModelIndex SqlMenuEntry::index(int row, int column, const QModelIndex &parent) const
  2. {
  3. if(!parent.isValid()) //parent为空,返回的是根节点的modelIndex,返回的同时,把节点数据指针(TreeNodePtr)保存在QModelIndex的internalPointer中,以便在其它函数中获取节点数据
  4. {
  5. if((row >= 0) && (row < mRootEntrys.size()))
  6. {
  7. return createIndex(row,column,mRootEntrys.at(row));
  8. }
  9. }else{
  10. TreeNodePtr parentNode = (TreeNodePtr)parent.internalPointer(); //返回子节点的modelIndex
  11. return createIndex(row,column,parentNode->childs[row]);
  12. }
  13. return QModelIndex();
  14. }
parent(const QModelIndex &child) 用于返回一个节点的父节点索引:

  1. QModelIndex SqlMenuEntry::parent(const QModelIndex &child) const
  2. {
  3. TreeNodePtr node = (TreeNodePtr)child.internalPointer();
  4. if(node->parent() == NULL)
  5. {
  6. return QModelIndex(); //根节点没有parent
  7. }else{
  8. return createIndex(0,1,node->parent());
  9. }
实现data(constQModelIndex&index,introle) 返回节点中的数据:
  1. QVariant SqlMenuEntry::data(const QModelIndex &index, int role) const
  2. {
  3. TreeNodePtr node = (TreeNodePtr)index.internalPointer();
  4. return node->data(role);
  5. }

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

  1. TreeView{
  2. anchors.fill: parent
  3. TableViewColumn {
  4. title: "Name"
  5. role: "name"
  6. }

  7. TableViewColumn {
  8. title: "Entry"
  9. role: "icon"
  10. }
  11. model:MenuEntryModel{}
  12. }
继续干活去了,明天再继续补充数据添加、删除和更新的相关经验。







分享到:QQ空间新浪微博腾讯微博微信百度贴吧QQ好友复制网址打印

您可能想查找下面的文章:

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

相关文章

  • 2017-05-26生成本地难码图片并在本地记录图片上的数字以作比较,图片记录
  • 2017-05-26产品原型图设计,产品原型图
  • 2017-05-26Linux内核系列—5.操作系统开发之特权级及特权级的转移,linux特权
  • 2017-05-26抽取的BaseFragment和LoadingPage,basefragment
  • 2017-05-26天兔监控服务器和mysql,redis等监控
  • 2017-05-222.5.4 AutoCompleteTextView(自动完成文本框)的基本使用
  • 2017-05-26手机安全卫士——主界面的开发,安全卫士主界面
  • 2017-05-26自定义轮播图片框架的使用,自定义播图片框架
  • 2017-05-26解析Service之你需要了解的一些东东,解析Service之东东
  • 2017-05-26android 自学日记(一)

文章分类

  • JavaScript
  • ASP.NET
  • PHP
  • 正则表达式
  • AJAX
  • JSP
  • ASP
  • Flex
  • XML
  • 编程技巧
  • Android
  • swift
  • C#教程
  • vb
  • vb.net
  • C语言
  • Java
  • Delphi
  • 易语言
  • vc/mfc
  • 嵌入式开发
  • 游戏开发
  • ios
  • 编程问答
  • 汇编语言
  • 微信小程序
  • 数据结构
  • OpenGL
  • 架构设计
  • qt
  • 微信公众号

最近更新的内容

    • Android动态加载Dex机制解析
    • [android] 手机卫士自定义控件的属性,android卫士
    • 使用软引用和弱引用防止内存溢出,引用防止内存溢出
    • 7.6.2 基于TCP协议的Socket通信(1)
    • retrofit2中ssl的Trust anchor for certification path not found问题,retrofit2anchor
    • 如何使用Android Studio开发Gradle插件
    • android:SpannableString的应用,TextView中某些文字的点击事件
    • Android开发学习——Android项目的目录结构,android项目
    • Android事件分发机制浅谈(一),android浅谈
    • 依赖ConstraintLayout报错,Could not find *****,Failed to resolve:*****,constraintlayout

关于我们 - 联系我们 - 免责声明 - 网站地图

©2020-2025 All Rights Reserved. linkedu.com 版权所有