Qt之QListView使用

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Qt之QListView使用相关的知识,希望对你有一定的参考价值。

参考技术A QListView可以用来以列表的形式展示数据,在Qt中使用model/View结构来管理数据与视图的关系,model负责数据的存取,数据的交互通过delegate来实现。

使用Qt自带的模型类 QStandardItemModel 即可。模型中的每个数据项都有一个与之对应的role来存储某一类数据。需要存取自定义数据可以使用UserRole,UserRole+1...

对于自定义数据类型,如果要使用QVariant,就必须使用Q_DECLARE_METATYPE注册。

模型的交互和绘制通过自定义delegate来实现,暂时没用到交互,先说下item的绘制。继承了QStyledItemDelegate后,重写paint函数处理item的样式,以及sizeHint函数返回item的大小:

在paint函数中,还可以获得当前item的状态,并设置不同的样式:

设置好模型后,再对QListView进行下属性设置:

模型的数据和展示都处理好后,运行效果如下:

Qt中提供了一个方便处理模型排序和过滤的类 QSortFilterProxyModel ,通过他可以非常方便的处理我们的model。将QListView展示的model设置成代理模型:

其中, m_proxyModel->setFilterRole(Qt::UserRole); 设置根据模型的某一项数据来处理模型的过滤。proxyModel可以设置过滤的方式,根据QString或者正则表达式来过滤:

对于列表中item的操作,可以是在delegate中处理交互事件,也可以通过QListView获取到所有选中item的QModelIndex,然后对模型本身进行修改。这里我选择的后者:

将QListView的 selectionBehavior 设置成 MultiSelection 即可。

对于多选的时候,模型的修改有一个坑。在设置了代理模型后,由于开启了动态排序模式,如果修改代理模型的数据,在第一个item修改数据后可能就不在当前过滤模型中,会被过滤掉,后面的item的QModelIndex就会变化,导致后续的修改失败。

有两个方法处理这个坑,一是不修改代理模型,修改源模型的数据。二是在修改模型数据的时候关闭代理模型的动态排序功能。

弄完大概是酱紫的:

Demo在这里:-> Github链接地址 。

Qt:更改 QListView 中的图标

【中文标题】Qt:更改 QListView 中的图标【英文标题】:Qt: Change the icon in a QListView 【发布时间】:2015-08-03 20:08:59 【问题描述】:

有没有办法在 QListView 显示后更改元素的图标?

我找不到使用DecorationRole(用于图标的角色)的方法来创建setData

使用的模型是自定义的QFileSystemModel,但默认实现只对EditRole有好处,所以要更改项目的名称。

我不知道如何覆盖 setData

目标是在鼠标悬停在项目上时更改图标(通过mouseMoveEvent

【问题讨论】:

子类 QFileSystemModel 并将 DecorationRole 填充到 setData?但是你需要知道在哪里设置图标,以便视图可以通过模型的data() 访问它。 【参考方案1】:

您需要继承 QListView 并实现当鼠标悬停在项目上时更改显示图标角色的行为。

这样的子类可以使用内部代理模型,这样它就不需要弄乱基础视图的绘制。只需通知代理给定项目的装饰角色数据已更改,基本视图就会知道该做什么。

【讨论】:

我不明白“改变显示图标的角色”是什么意思。 @user3842408 源模型提供了两个图标,默认在装饰角色下,一个悬停在自定义角色下。代理将针对装饰角色数据的请求重定向到同一角色或自定义悬停角色,具体取决于来自子类视图的方向。

以上是关于Qt之QListView使用的主要内容,如果未能解决你的问题,请参考以下文章

Qt - 如何将 QListView 项目转移到另一个 QListView?

QT学习_QListView使用

Qt:更改 QListView 中的图标

信号和插槽的连接(关于 qlistview) - Qt

Qt:自定义 QListView 和实时控件

什么是最适合 QAbstractListModel 和 QListView 的 Qt 容器