• 17499阅读
  • 11回复

QTableView实现行选和复选框 [复制链接]

上一主题 下一主题
离线wvins
 
只看楼主 倒序阅读 楼主  发表于: 2009-01-14
— 本帖被 XChinux 从 General Qt Programming 移动到本区(2011-01-02) —
[img] [/img]

总算搞出来了!
整理下这两天的折腾。
----------------------------------------
1.QListView不支持多列,群里面还有位兄弟遇到过
2.想使用QItemDelegate的createWidget方法,在第一列绘制一个QCheckBox,因为CheckBox能够提供勾选和图标,但是createWidget方法只有在编辑的时候才会触发
3.重载paint方法,在paint方法中绘制一个QCheckBox,不能很好的支持排序,排序后第一列和后面的列错位。
...
年会了,回头补上
----------------------------------------
[ 此贴被wvins在2009-01-15 12:39重新编辑 ]
离线wd007

只看该作者 1楼 发表于: 2009-01-15
好帖阿,感谢楼主
欢迎访问我的博客,一起学习提高
http://blog.csdn.net/qter_wd007
离线wvins
只看该作者 2楼 发表于: 2009-01-15
首先设置QTableView的属性,如图:
[img]http:// [/img]
其中SelectionBehavior设置成SelectRows行选
showGrid设置成false,不显示表格
sortingEnabled设置成true,支持排序。(据说这个功能需要实现sort方法或者使用ProxyModel,还没有具体实验)
-------------------
然后,自定义一个ListModel
对于第一列数据要能够支持CheckBox,要能够显示图标,要能够显示文本
对应的就要返回Qt::CheckStateRole、Qt::DecorationRole、Qt::DisplayRole相应的数据。
我的实现如下:
QVariant ListModel::data(const QModelIndex &index, int role) const
{
if (!index.isValid())
return QVariant();

ListItem *item = static_cast<ListItem*>(index.internalPointer());

if (index.column()==0)//请求第一列数据
{
switch(role)
{
case Qt::DisplayRole://返回标题
return item->caption();
case Qt::DecorationRole://返回图标
if (item->readed())
return readed;
else
return unRead;
case Qt::CheckStateRole: //返回单选框状态
if (item->readed()) //这里由于QCheckBox是三态的,不应该简单的返回true,false
return Qt::Checked;
else
return Qt::Unchecked;
default:
return QVariant();
}
}
if ((index.column()==1) && (role==Qt::DisplayRole))
return item->description();
return QVariant();
}
其次,光是有这些还不够,QTableView需要通过ListMode的flags方法知道某个单元格是不是需要绘制CheckBox,
我的flags方法实现如下:
Qt::ItemFlags ListModel::flags(const QModelIndex &index) const
{
if (!index.isValid())
  return 0;
if (index.column()==0)//对于第一列设置标志位
  return Qt::ItemIsEnabled | Qt::ItemIsSelectable | Qt::ItemIsUserCheckable;
//CheckBox
return Qt::ItemIsEnabled | Qt::ItemIsSelectable;
}
最后,结合这两样应该就能够正常显示了,不过这个时候的单选框还只是个摆设,需要实现setData方法让复选框可用,我的setData方法实现如下:
bool ListModel::setData(const QModelIndex &index, const QVariant &value, int role)
{
if (!index.isValid())
  return false;

ListItem *item= static_cast<ListItem*>(index.internalPointer());
if ((index.column()==0)&&(role==Qt::CheckStateRole))
//CheckStateRole表示执行复选框状态的数据更新
{
  if (value == Qt::Checked)
  item->setReaded(true);
  else
  item->setReaded(false);
}
}
========================================
最后附上我的代码和数据库,希望对大家有帮助。
源代码 QtRSSReader.rar (293 K) 下载次数:480
这也是我的RSS阅读器目前位置的所有代码,
我才发现按QWidget为单位划分模块是个不错的想法,测试也很方便。
这让我的RSS阅读器的代码不至于太混乱
离线archldx
只看该作者 3楼 发表于: 2009-04-22
太感谢了,不管好坏,都得感谢
离线fengzhishang

只看该作者 4楼 发表于: 2009-05-27
真的,还可以·
离线hys97

只看该作者 5楼 发表于: 2009-06-05
楼主的精神可嘉!写得很详细,学习了!
离线wu_java
只看该作者 6楼 发表于: 2009-06-26
大哥,好人呀
离线robertkun

只看该作者 7楼 发表于: 2009-07-29
向楼主学习
                                              简单的生活使人快乐!
离线alan2008

只看该作者 8楼 发表于: 2009-07-30
学习!
离线shiroki

只看该作者 9楼 发表于: 2009-07-30
如果用QStandardItemModel的话它的item直接支持 setCheckable, 你就不用自己画checkbox了
--
shiro is White
ki is tree
http://www.cuteqt.com
论坛 http://www.cuteqt.com/bbs
博客 http://www.cuteqt.com/blog
博客镜像: http://sites.cuteqt.com/cuteqt
Linux/Qt/嵌入式讨论群 http://qun.qq.com/air/5699823
离线talent
只看该作者 10楼 发表于: 2010-04-21
thank you!
离线talent
只看该作者 11楼 发表于: 2010-04-21
thank you!
快速回复
限100 字节
 
上一个 下一个