zoukankan      html  css  js  c++  java
  • QT中Qtableview视图表格中点击表头进行排序

    用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等其他的类本人没测试。按道理来说,应该也是有效的。

  • 相关阅读:
    Android Studio 单刷《第一行代码》系列 05 —— Fragment 基础
    Android Studio 单刷《第一行代码》系列 04 —— Activity 相关
    Android Studio 单刷《第一行代码》系列 03 —— Activity 基础
    Android Studio 单刷《第一行代码》系列 02 —— 日志工具 LogCat
    Android Studio 单刷《第一行代码》系列 01 —— 第一战 HelloWorld
    IDEA 内网手动添加oracle,mysql等数据源,以及server returns invalid timezone错误配置
    eclipse maven设置
    IntelliJ IDE 常用配置
    eclipse maven 常见问题解决方案
    Maven 安装和配置
  • 原文地址:https://www.cnblogs.com/felix-wang/p/6290087.html
Copyright © 2011-2022 走看看