博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
QT中Qtableview视图表格中点击表头进行排序
阅读量:5163 次
发布时间:2019-06-13

本文共 2190 字,大约阅读时间需要 7 分钟。

用QT写了一个小工具,主要是对Excel中大量的数据进行计算和显示。

写了有一段时间,然后断断续续的做一些修改和完善。

因为要显示的数据有多列,很自然的会想到要能够对显示的数据进行排序。如果直接操作model里的数据,不太方便,因为最好是能由用户自己选择按哪一列进行排序。如果通过信号槽机制,也不是很方便。然后找到QTableView下有一个setSortingEnabled()的函数。在将该函数设置为True后,在鼠标移动到表头上某一列时,可以看到出现了可以用于提示点击的上三角或下三角标志,但是,在鼠标点击过后没有任何反应。本人以为上述函数被设置为True后,还要对每一列的排序用代码实现,想想就发怵,作罢。后来继续研究,说是可以通过信号槽,先获取鼠标点击表头的信号,然后映射到一个sortByColumn()的排序槽函数上,用于排序。因为本人对信号槽也只是入门,编写起来发现也有一些问题不好解决。最后在中文网上几乎找不到好的解决办法,关键是并没有相关度很高的内容。于是,就试着用了一下google。一会就找到了好几个类似的问题,网友也提出了几种解决方案。

首先说一下原因:

将setSortingEnabled()函数设为True后,点击表头排序的背后调用的是sortByColumn()这个函数。

在qtableview.cpp源文件中有sortByColumn()函数的实现代码:

 

1 void QTableView::sortByColumn(int column) 2 { 3     Q_D(QTableView); 4  5     if (!d->model) 6         return; 7     bool ascending = (horizontalHeader()->sortIndicatorSection()==column&& horizontalHeader()->sortIndicatorOrder()==Qt::DescendingOrder); 8     Qt::SortOrder order = ascending ? Qt::AscendingOrder : Qt::DescendingOrder; 9     horizontalHeader()->setSortIndicator(column, order);10     d->model->sort(column, order);11 }

sortByColumn()函数最后调用的model的sort函数。

由于本人使用的model类型是QSqlQueryModel,该类型继承自QAbstractTableModel类,而该类又继承自QAbstractItemModel。

QSqlQueryModel和QAbstractTableModel这两个类本身是没有sort函数的,自能使用QAbstractItemModel类的sort函数。

QAbstractItemModel类中的sort函数形式如下:

virtual void sort(int column, Qt::SortOrder order = Qt::AscendingOrder)

它是一个虚拟函数,也就是说没有具体的实现,是无法真正用于排序的。

所以由此产生一个思路,如果将model的类型转换成一个重写了sort函数的model类,那么也许就可以通过点击表头进行排序了。

找一下QAbstractItemModel有哪些子类,通过一番搜索,找到QAbstractProxyModel、QSqlTableModel等子类都有重写的sort函数。

我们把之前QSqlQueryModel的model转换为QAbstractProxyModel试一下,看是否有效。

1 QSqlDatabase db_output1 = QSqlDatabase::database("db_output1_connection");2 QSqlQueryModel *model = new QSqlQueryModel();3 QString model_query;4 model_query = QString("Select Airline ,Airline1, Ratio, Angle, Year, Summer, Winter from [%1$]").arg(show_sheet_name);5 model->setQuery(model_query,db_output1);6 QSortFilterProxyModel *sqlproxy = new QSortFilterProxyModel(this);7 sqlproxy->setSourceModel(model);8 ui->tableView->setModel(sqlproxy);

这是没有排序时,显示的结果。

下图是单击表头中的日班次后排序的结果。

下图是单击另一列的表头(费率)后排序的结果。其他各列的排序也均有效。

QSqlTableModel等其他的类本人没测试。按道理来说,应该也是有效的。

转载于:https://www.cnblogs.com/felix-wang/p/6290087.html

你可能感兴趣的文章
Java中反射的学习与理解(一)
查看>>
C语言初学 俩数相除问题
查看>>
B/S和C/S架构的区别
查看>>
[Java] Java record
查看>>
jQuery - 控制元素显示、隐藏、切换、滑动的方法
查看>>
postgresql学习文档
查看>>
Struts2返回JSON数据的具体应用范例
查看>>
js深度克隆对象、数组
查看>>
socket阻塞与非阻塞,同步与异步
查看>>
团队工作第二天
查看>>
System类
查看>>
tableView
查看>>
Happy Great BG-卡精度
查看>>
Xamarin Visual Studio不识别JDK路径
查看>>
菜鸟“抄程序”之道
查看>>
Ubuntu下关闭防火墙
查看>>
TCP/IP 邮件的原理
查看>>
原型设计工具
查看>>
windows下的C++ socket服务器(4)
查看>>
css3 2d转换3d转换以及动画的知识点汇总
查看>>