Qt——用于表格QTableView的模型
如果想使用表格来呈现数据,Qt提供了一个方便的部件QTableWidget,但是直接用它实现一些功能可能比较困难。这里将介绍一种强大、灵活的方式来操作表格。
一、模型/视图架构
在这个架构中,模型用于存储数据,视图用于呈现数据,除此之外,还有一个称为委托的部分,委托显示视图中的每一项,并为可编辑的项提供合适的编辑器。
三者的关系如下图所示——

这篇博客只介绍模型/视图的部分,接下来用一个简单的例子来说明如何使用。
二、要实现的功能
以网易云音乐为例,它的部分搜索界面是这样的:

现在,我们依照网易云音乐做一个下面的窗口,并实现额外的一些功能。

要实现的功能:
1.网上搜索:从网上搜索歌曲的数据并呈现在左边的表格中;
2.本地搜索并选中:在左边的表格中进行搜索,选中与关键字相匹配的行;
3.本地搜索并过滤:在左边的表格中进行搜索,只显示与关键字相匹配的行,过滤隐藏不匹配的行。
三、联网搜索
1.准备工作
左边的表格使用 QTableView 。
为了存储数据,需要使用合适的模型,在这里我们使用 QStandardItemModel 。
同时为了实现过滤,需要另一个代理模型 QSortFilterProxyModel 。
//数据模型
class MusicInfoModel : public QStandardItemModel
{
public:
void loadData(const QString &strKeyword);//用于加载网上搜索得到的数据
}
//主窗口
class MainWidget : public QWidget
{
private slots:
void searchOnlineSlot(); //网上搜索
void searchAndSelcLocalSlot(); //本地搜索并选择
void searchAndFilterLocalSlot(); //本地搜索并过滤
private:
MusicInfoModel *m_pInfoModel; //数据模型
QSortFilterProxyModel *m_pFilterModel; //过滤代理模型
}
以上只列出重要的成员变量和成员函数。
为了方便加载数据,我们将QStandardItemModel子类化,在子类中声明一个加载数据的函数 loadData 。
在主窗口的构造函数中初始化视图和模型——
m_pInfoModel = new MusicInfoModel(this);
m_pFilterModel = new QSortFilterProxyModel(this);
m_pFilterModel->setSourceModel(m_pInfoModel);
ui.musicInfoTblView->setModel(m_pFilterModel);
从上面可以看到,表格的视图模型是代理模型filterModel,而不是实际包含数据的模型infoModel。
2.加载数据
接下来网上搜索,获得数据并加载到表格中
首先定义歌曲信息的数据结构
//歌曲信息的数据结构
struct SongInfo
{
public:
QString strName; //歌曲标题
QString strSinger; //歌手名字
QString strAlbum; //专辑名称
};
完成数据模型中加载数据的函数:
void MusicInfoModel::loadData(const QString &strKeyword)
{
QList<SongInfo> listSongInfo; //歌曲信息的list //...省略的步骤
//根据关键字strKeyword从网上搜索
//并将搜索结果存储到listSongInfo中 //清除数据模型中之前存在的数据,并重新设置表头(因为clear会把表头也清除掉)
clear();
setHorizontalHeaderLabels(QStringList() << QString::fromLocal8Bit("音乐标题") << QString::fromLocal8Bit("歌手") << QString::fromLocal8Bit("专辑"));
//遍历list,将数据存在表中
for (SongInfo songItem : listSongInfo)
{
QList<QStandardItem *> listItems;
QStandardItem *pTitle = new QStandardItem(songItem.strName);
QStandardItem *pSinger = new QStandardItem(songItem.strSinger);
QStandardItem *pAlbum = new QStandardItem(songItem.strAlbum);
listItems << pTitle << pSinger << pAlbum;
appendRow(listItems);//加载一行数据
}
}
注意:表中的每一项是一个QStandardItem,在加载一行之前,需要先把他们存储在一个QList中,然后调用appendRow函数,一次完成加载3列。
接下来,我们在主界面中调用数据模型对象的loadData函数,即可将数据全部填到表格中。
四、本地搜索并过滤
过滤很简单,只需要使用QSortFilterProxyModel中的相关函数。
void MainWidget::searchAndFilterLocalSlot()
{
QString strKeyword = ui.textEdit->text();
m_pFilterModel->setFilterFixedString(strKeyword);//根据字符串过滤
}
一些有用的函数:
void setFilterKeyColumn(int column) :设置根据表的哪一列进行过滤,默认值为0,如果设置成-1,则会根据所有列进行搜索。
setFilterFixedString(const QString &) :根据固定的字符串进行过滤。
setFilterRegExp(const QRegExp &) :根据正则表达式进行过滤。
五、本地搜索并选中
void MainWidget::searchAndSelcLocalSlot()
{
QItemSelection selection;
int iFirstSelcRow = -1;
for (int i = 0; i < m_pFilterModel->rowCount(); ++i)
{
//获得每一行的歌名、歌手名、专辑名
QModelIndex songIndex = m_pFilterModel->index(i, 0);
QModelIndex singerIndex = m_pFilterModel->index(i, 1);
QModelIndex albumnIndex = m_pFilterModel->index(i, 2);
QString strSong = m_pFilterModel->data(songIndex).toString();
QString strSinger = m_pFilterModel->data(singerIndex).toString();
QString strAlbumn = m_pFilterModel->data(albumnIndex).toString();
//判断是否符合条件
if (strSong.contains(strKeyword) || strSinger.contains(strKeyword) || strAlbumn.contains(strKeyword))
{
if (iFirstSelcRow == -1)
{
iFirstSelcRow = i;
}
//增加选中项
QItemSelection rowSelc(songIndex, songIndex);
selection.merge(rowSelc, QItemSelectionModel::Select);
}
}
//清除之前所有选中项,并选中现在的所有匹配项
QItemSelectionModel *pSelcModel = ui.musicInfoTblView->selectionModel();
pSelcModel->clearSelection();
pSelcModel->select(selection, QItemSelectionModel::Rows | QItemSelectionModel::Select);
//视图滚动到第一个选中项的位置
if (iFirstSelcRow != -1)
{
ui.musicInfoTblView->scrollTo(m_pFilterModel->index(iFirstSelcRow, 0));
}
}
最终的简陋窗口:

以上只是视图/模型的使用作简单介绍,更多用法还请在实践中自行查找官方文档。
Qt——用于表格QTableView的模型的更多相关文章
- Qt实现表格控件-支持多级列表头、多级行表头、单元格合并、字体设置等
目录 一.概述 二.效果展示 三.定制表头 1.重写数据源 2.重写QHeaderView 四.设置属性 五.相关文章 原文链接:Qt实现表格控件-支持多级列表头.多级行表头.单元格合并.字体设置等 ...
- Qt之表格控件蚂蚁线
一.蚂蚁线 摘自互动百科:在图像影像软件中表示选区的动态虚线,因为虚线闪烁的样子像是一群蚂蚁在跑,所以俗称蚂蚁线.在Poshop,After Effect等软件中比较常见. 背景:用过excel的同学 ...
- Qt实现表格树控件-自绘树节点虚线
目录 一.开心一刻 二.自绘树节点? 三.效果展示 四.实现思路 1.可扩展接口 2.函数重写 3.同步左侧表头 五.相关文章 原文链接:Qt实现表格树控件-自绘树节点虚线 一.开心一刻 一程序员第一 ...
- Qt实现表格树控件-支持多级表头
目录 一.概述 二.效果展示 三.实现方式 四.多级表头 1.数据源 2.表格 3.QStyledItemDelegate绘制代理 五.测试代码 六.相关文章 原文链接:Qt实现表格树控件-支持多级表 ...
- qt model/view 架构自定义模型之QFileSystemModel
# -*- coding: utf-8 -*- # python:2.x #QFileSystemModel """ Qt 内置了两种模型:QStandardItemM ...
- qt model/view 架构自定义模型之QStringListModel
# -*- coding: utf-8 -*- # python:2.x #QStringListModel #QStringListModel 是最简单的模型类,具备向视图提供字符串数据的能力. # ...
- Qt 学习之路:模型-视图高级技术
PathView PathView是 QtQuick 中最强大的视图,同时也是最复杂的.PathView允许创建一种更灵活的视图.在这种视图中,数据项并不是方方正正,而是可以沿着任意路径布局.沿着同一 ...
- Qt将表格table保存为excel(odbc方式)
首先是保存excel的方法,可参照: http://dzmlmszp.blog.163.com/blog/static/179271962014819111812531/ ok,进入正题. 现在我有一 ...
- Qt在表格中加入控件
任务:使用QTableWidget动态生成表格,在每行的某两列中加入QComboBox下拉框控件和QPushButton按钮控件 有添加,删除,编辑功能,每行的按钮可以浏览文件夹并选择文件 1.新建一 ...
随机推荐
- Flutter - Finished with error: FormatException: Bad UTF-8 encoding 0xc3 (at offset 169)
方案1: 更改项目的Encoding方式 File -> Settings -> Editor, choose "File Encodings", change Pr ...
- list add() 和 addall()的区别
http://blog.tianya.cn/post-4777591 如果有多个已经被实例化的List 集合,想要把他们组合成一个整体,并且,这里必须直接使用List 自身提供的一个方法List.ad ...
- iOS逆向+越狱
感觉本文涉及内容有点多的,但是自己不愿意写太多,就简单的谢谢关于ios上手的东西吧 初级入手不免要用到,pp助手,i4 tools等 iOS逆向-ipa包重签名及非越狱手机安装多个应用 1.常识 我们 ...
- WebGL——osg框架学习四
这篇我们接着来看一下DrawEntityActor类,我们来看看这个继承DrawActor的类到底做了什么事.我们之前学习了Drawable对应的DrawActor,那么我们类比的来看Drawable ...
- 【NLP】彻底搞懂BERT
# 好久没更新博客了,有时候随手在本上写写,或者Evernote上记记,零零散散的笔记带来零零散散的记忆o(╥﹏╥)o..还是整理到博客上比较有整体性,也方便查阅~ 自google在2018年10月底 ...
- mkdir命令详情
基础命令学习目录首页 原文链接:https://blog.csdn.net/zwlove5280/article/details/74618041 mkdir 是创建目录的命令. 创建一级目录 mkd ...
- lastlog命令详解
基础命令学习目录首页 原文链接:https://www.cnblogs.com/qiyebao/p/4331078.html last 显示所有用户最后登录信息(会显示系统用户) last -u 50 ...
- comet4j推送 405/500 JSON转换异常
因为Comet4J工作在NIO方式下,所以我们需要调整服务器连接器配置,更换为NOI连接器. 打开server.xml文件将找到原先的连接器配置: <Connector executor=&qu ...
- Java第一次试验
北京电子科技学院(BESTI) 实 验 报 告 课程:Java程序设计 班级:1352 姓名:朱国庆 学号:20135237 成绩: ...
- 20172325 2016-2017-2 《Java程序设计》第四周学习总结
20172325 2016-2017-2 <Java程序设计>第四周学习总结 教材学习内容总结 1.对类.对象.声明变量的定义和属性有了进一步的了解 2.学会如何编写一个类并运用到需要的程 ...