在qt中,用到最多就是model/view的结构来表示数据层及表示层的关系。model用于给view提供数据。那如何来实现一个简单的树形model呢。

实现一个自己的model需要重载以下的方法:

  1. QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const;
  2. bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole);
  3. int rowCount(const QModelIndex &parent = QModelIndex()) const;
  4. int columnCount(const QModelIndex &parent = QModelIndex()) const<pre name="code" class="cpp">QVariant headerData(int section, Qt::Orientation orientation,
  5. int role = Qt::DisplayRole) const;
  6. bool setHeaderData(int section, Qt::Orientation orientation, const QVariant &value,
  7. int role = Qt::EditRole);
  8. QModelIndex index(int row, int column,
  9. const QModelIndex &parent = QModelIndex()) const;
  10. QModelIndex parent(const QModelIndex &child) const;
  11. virtual Qt::ItemFlags flags(const QModelIndex &index) const;

下面通过一个小例子来说明每个方法的作用。想实现下面一个树形结构。

既然实现一个model里面肯定得构造自己的数据结构

  1. class RowNode
  2. {
  3. public:
  4. RowNode() { m_pNode = NULL; }
  5. ~RowNode() {}
  6. public:
  7. inline void setParent(RowNode *rowNode) { m_pNode = rowNode; }
  8. inline RowNode *parent() { return m_pNode; }
  9. private:
  10. RowNode *m_pNode;
  11. };

model构造里

  1. m_child1 = new RowNode();
  2. m_child2 = new RowNode();
  3. m_child2->setParent(m_child1);

1)data方法:这个方法用于提供model所需要的各种数据。根据不同的index跟role返回不同的值。

  1. QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const;
  2. {
  3. <pre name="code" class="cpp">if (Qt::DisplayRole == role)
  4. {
  5. RowNode *pRowNode = static_cast<RowNode *>(index.internalPointer());
  6. if (m_child1 == pRowNode)
  7. {
  8. if (0 == index.column())
  9. {
  10. return "Test";
  11. }
  12. else if (1 == index.column())
  13. {
  14. return "Icon";
  15. }
  16. else if (2 == index.column())
  17. {
  18. return "comboBox";
  19. }
  20. }
  21. else
  22. {
  23. if (0 == index.column())
  24. {
  25. return "col0";
  26. }
  27. else if (1 == index.column())
  28. {
  29. return "col1";
  30. }
  31. else
  32. {
  33. return "col2";
  34. }
  35. }
  36. }
  37. else
  38. return QVariant();
  39. }

2)setData:这个方法用于设置model的各种数据,根据不同的index跟role的值.原理跟data一样,这里就不直接写了,直接返回True.

  1. bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole);
  2. {
  3. return true;
  4. }

3)rowCount:用于设置行数。需要注意的是返回是指parent下面有几个子,而不是指整个TableView有多少行。因为显示树形的话,返回的RowCount只是指那个父结点有几个子。

  1. int rowCount(const QModelIndex &parent = QModelIndex()) const;
  2. {
  3. <pre name="code" class="cpp">if (! parent.isValid())
  4. {
  5. return 1;
  6. }
  7. else
  8. {
  9. RowNode *pNode = static_cast<RowNode *>(parent.internalPointer());
  10. if (pNode == m_child1)
  11. {
  12. return 1;
  13. }
  14. else
  15. {
  16. return 0;
  17. }
  18. }

4)columnCount:用于设置列数,这个是整个TableView的列数。

  1. int columnCount(const QModelIndex &parent = QModelIndex()) const;
  2. {
  3. return 4;
  4. }

5)headerData及setHeadData

  1. QVariant headerData(int section, Qt::Orientation orientation,
  2. int role = Qt::DisplayRole) const;
  3. {
  4. <pre name="code" class="cpp">    if (orientation == Qt::Vertical)
  5. {
  6. if (Qt::DisplayRole == role)
  7. {
  8. return "2";
  9. }
  10. }
  11. if (Qt::DisplayRole == role)
  12. {
  13. return "1";
  14. }
  15. else
  16. return QVariant();

}
 bool setHeaderData(int section, Qt::Orientation orientation, const QVariant &value, int role = Qt::EditRole);
{
return true;
}


同data跟setData一样,但是是用于设置header的值,就是标题行及固定列的值。

6)index:用于设置返回的index的值。

  1. QModelIndex index(int row, int column,
  2. const QModelIndex &parent = QModelIndex()) const;
  3. {
  4. <pre name="code" class="cpp">    if (! parent.isValid())
  5. {
  6. return createIndex(row, column, m_child1);
  7. }
  8. else
  9. {
  10. return createIndex(row, column, m_child2);
  11. }

}


7)parent:用于设置父index。

  1. QModelIndex parent(const QModelIndex &child) const;
  2. {
  1. RowNode *pRowNode = static_cast<RowNode *>(child.internalPointer());
  2. if (pRowNode == m_child2)
  3. {
  4. return createIndex(0, 0, m_child1);
  5. }
  6. return QModelIndex();
  7. }

8)flags:用于返回model一些flags,如是否可以编辑的话,会加上Qt::itemIsEditable.

  1. virtual Qt::ItemFlags flags(const QModelIndex &index) const;
  2. {
  3. <pre name="code" class="cpp">    Qt::ItemFlags oFlags = QAbstractItemModel::flags(index);
  4. return oFlags | Qt::ItemIsEditable;
  5. }

这样一个简单的model就实现了。

http://blog.csdn.net/hpjx1987/article/details/28005011

Qt中如何写一个model的更多相关文章

  1. Qt中如何写一个model(自定义一个RowNode,我没有碰到过)

    在qt中,用到最多就是model/view的结构来表示数据层及表示层的关系.model用于给view提供数据.那如何来实现一个简单的树形model呢. 实现一个自己的model需要重载以下的方法: Q ...

  2. mvc中动态给一个Model类的属性设置验证

    原文:mvc中动态给一个Model类的属性设置验证 在mvc中有自带的验证机制,比如如果某个字段的类型是数字或者日期,那么用户在输入汉字或者英文字符时,那么编译器会自动验证并提示用户格式不正确,不过这 ...

  3. C语言中如何写一个简单可移植而又足够随机的随机数生成器

    在C语言中标准库中的随机数产生函数的返回可能不是最优的,因为有些随机数生成器的低位并不随机,而另一些返回随机数的函数实现上又太复杂鸟.所以rand()%N并不是一个好方法,牛人给出的建议是使用: ra ...

  4. QT 中如何实现一个简单的动画

    QT可以实现一下简单的动画,比如 运动的时钟 闪烁的按钮. 动画的实现: (1)创建一个定时器 (2)调用QWidget::update()通知界面重绘 实现一个按钮闪烁的例子: circlewidg ...

  5. (转载)QT中PRO文件写法的详细介绍,很有用,很重要!

    版权声明:本文为博主原创文章,未经博主允许不得转载. 在QT中,有一个工具qmake可以生成一个makefile文件,它是由.pro文件生成而来的,.pro文件的写法如下: 1. 注释从“#”开始,到 ...

  6. QT中PRO文件写法的详细介绍

    学习Qt时,发现有些知识看了不经常用就忘了,以下是书本上写的一些关于qmake的相关知识,自己看后,打算把一些经常用到的记下来,整理整理. Qt程序一般使用Qt提供的qmake工具来编译. qmake ...

  7. 【SSH网上商城项目实战24】Struts2中如何处理多个Model请求

       转自: https://blog.csdn.net/eson_15/article/details/51465067 1. 问题的提出 Struts2中如果实现了ModelDriven<m ...

  8. Qt中的多线程与线程池浅析+实例

    1. Qt中的多线程与线程池 今天学习了Qt中的多线程和线程池,特写这篇博客来记录一下 2. 多线程 2.1 线程类 QThread Qt 中提供了一个线程类,通过这个类就可以创建子线程了,Qt 中一 ...

  9. 从零开始写一个武侠冒险游戏-8-用GPU提升性能(3)

    从零开始写一个武侠冒险游戏-8-用GPU提升性能(3) ----解决因绘制雷达图导致的帧速下降问题 作者:FreeBlues 修订记录 2016.06.23 初稿完成. 2016.08.07 增加对 ...

随机推荐

  1. 小课堂Week11 会说话的代码

    小课堂Week11 会说话的代码 今天主要讨论下,在编码过程中和"命名"相关的问题.因为命名方法比较自由,如果要提高可读性,我们需要尽量使其符合正规的英文语法习惯. 变量/属性 通 ...

  2. Python开发【第一篇】Python基础之反射

    反射 反射的作用:反射得作用是提高代码可读行. __import__导入模块和import导入模块的区别: __import__导入模块是通过字符串进行导入. import是常用得导入模块方法. 扩展 ...

  3. SQLserver中的xp_cmdshell

    shell是用户与操作系统对话的一个接口,通过shell告诉操作系统让系统执行我们的指令 xp_cmdshell在sqlserver中默认是关闭的存在安全隐患. --打开xp_cmdshell ;;R ...

  4. Linux内核目录

    linux目录结构 目录 1.树状目录结构图 2./目录 3./etc/目录 4./usr/目录 5./var/目录 6./proc/目录 7./dev/目录 该文章主要来自于网络进行整理. 目录结构 ...

  5. vagrant在windows下的使用

    vagrant在windows下的使用 下载安装 VirtualBox :https://www.virtualbox.org/ 下载安装 Vagrant :http://www.vagrantup. ...

  6. 用 HTML 编写博客栏目

    “生活中不是缺少美,而是缺少发现美的眼睛. -----罗丹 在之前阅读师哥师姐们博客的时候,尤其是那些感觉非常优秀博客的时候就注意到了一个东西..... ----------------------- ...

  7. sql Mirroring

    http://www.codeproject.com/Articles/109236/Mirroring-a-SQL-Server-Database-is-not-as-hard-as http:// ...

  8. Daily Scrum 11.9

    摘要:本次的meeting主要是继续讨论程序的问题以及单元测试和集成测试等,本次为1.01版本.本次的Task列表如下: Task列表 出席人员 Today's Task Tomorrow's Tas ...

  9. window对象的属性方法名造成的命名冲突

    事件起因: 一次开发中需要获取一个数组的长度,写下如此代码 function func(arr){ length = arr.length; ......//相关操作 } 程序在chrome下正常运行 ...

  10. Winform 文件控件 - 转

    1. OpenFileDialog private void openFileDialogBTN_Click(object sender, System.EventArgs e) { OpenFile ...