在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(自定义一个RowNode,我没有碰到过)的更多相关文章

  1. Qt中如何写一个model

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

  2. C++在使用Qt中SLOT宏须要注意的一个小细节

    大家都知道C++虚函数的机制,对于基类定义为虚函数的地方,子类假设覆写,在基类指针或者引用来指向子类的时候会实现动态绑定. 但假设指针去调用非虚函数,这个时候会调用C++的静态绑定,去推断当前的指针是 ...

  3. C++在使用Qt中SLOT宏需要注意的一个小细节

    大家都知道C++虚函数的机制,对于基类定义为虚函数的地方,子类如果覆写,在基类指针或者引用来指向子类的时候会实现动态绑定. 但如果指针去调用非虚函数,这个时候会调用C++的静态绑定,去判断当前的指针是 ...

  4. 6.关于QT中的内存管理,动态的制作,动态库的调用,静态库的制作

     一  QT的内存管理 1  QT中的内存管理是QObject来管理的 2  QT中的内存管理没有cocos2dx中的引用计数 3  组件能够指定父对象 QTimer *timer = QTime ...

  5. QT中QWidget、QDialog QMainWindow

    继承关系:在Qt中所有的类都有一个共同的基类QObject ,QWidget直接继承与QPaintDevice类,QDialog.QMainWindow.QFrame直接继承QWidget 类. QW ...

  6. Qt中的内存回收机制

    Qt中的内存回收机制 在Qt中创建对象的时候会提供一个 Parent对象指针(可以查看类的构造函数),下面来解释这个parent到底是干什么的. QObject是以对象树的形式组织起来的.当你创建一个 ...

  7. CI中的控制器中要用model中的方法,是统一写在构造器方法中,还是在每一个方法中分别写

    Q: CI中的控制器中要用model中的方法,是统一写在构造器方法中,还是在每一个方法中分别写 A: 建议统一写,CI框架会自动识别已经加载过的类,所以不用担心重复加载的问题 class C_User ...

  8. Qt中,当QDockWidget的父窗口是一个不可以拖动的QTabWidget的时候实现拖动的方法

    之前在做有关QDockWidget的内容时候遇到了瓶颈,那就是窗口弹出来之后拖动不了,也不可以放大和缩小,若是弹出来之后设置成了window的flags,也不可以拖动,而且也不是需要的效果. 1.弹出 ...

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

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

随机推荐

  1. web app开发中 iPhone、iPad默认按钮样式问题

    webapp开发过程中,用html5+css3很方便,而且可以很方便的编译到Android ios等不同平台,但是ios需要单独处理一下,不然会出现一些想象不到的问题.下面就介绍一下各种问题的解决方法 ...

  2. oracle学习(1)

    1.安装完oracle数据库后,远程第一次无法登陆,需要进入sys用户后,更改以此后才有效. 2.TNS去读取配置的时候,如果在环境变量中已经配置了 TNS_ADMIN 后,则直接从此目录下读取. 3 ...

  3. union 和 union all 的区别

    Union因为要进行重复值扫描,所以效率低.如果合并没有刻意要删除重复行,那么就使用Union All  两个要联合的SQL语句 字段个数必须一样,而且字段类型要“相容”(一致): 如果我们需要将两个 ...

  4. CSS3几个速记标签2

    @font-face:CSS3允许使用自己的字体,用户会自动下载     语法:@font-face{font-family:---:src:url(---)}     如果要使用粗体,必须新添加另一 ...

  5. HDU 4764 Stone(博弈)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4764 题目大意:Tang和Jiang玩石子游戏,给定n个石子,每次取[1,k]个石子,最先取完的人失败 ...

  6. hdu 1250 Hat's Fibonacci(高精度数)

    //  继续大数,哎.. Problem Description A Fibonacci sequence is calculated by adding the previous two membe ...

  7. 使用struts2+hibernate的增、删、改、查构架简单的学生管理系统

    工程环境:MyEclipse8.5 其他配置:Hibernate框架+jtds链接数据库驱动+Sql2008数据库+MyEclipse serevr+JDK1.7 开发环境:Win7x64 这个项目用 ...

  8. C# 制作Zip压缩包

    压缩包制作也是很多项目中需要用到的功能.比如有大量的文件(假设有10000个)需要上传,1个1个的上传似乎不太靠谱(靠,那得传到什么时候啊?),这时我们可以制作一个压缩包zip,直接传这个文件到服务器 ...

  9. asp.net mvc上传头像加剪裁功能介绍

    正好项目用到上传+剪裁功能,发上来便于以后使用. 我不能告诉你们其实是从博客园扒的前台代码,哈哈. 前端是jquery+fineuploader+jquery.Jcrop 后台是asp.net mvc ...

  10. Dreamweaver 添加 cakephp ctp后缀名

    Dreamweaver 默认是不支持ctp文件高亮的,即使用Dreamweaver打开ctp文件,也只能像记事本一样编辑 但是我们可以通过修改两个文件,来添加Dreamweaver对ctp文件的扩展支 ...