1. 程式人生 > >QT中Qtableview視圖表格中點選表頭進行排序

QT中Qtableview視圖表格中點選表頭進行排序

因為要顯示的資料有多列,很自然的會想到要能夠對顯示的資料進行排序。如果直接操作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等其他的類本人沒測試。按道理來說,應該也是有效的。

一點感悟:

遇到技術問題,要善於將問題準確提煉出來,是自己搜尋也好,或是請教他人都有幫助。往往是對遇到的問題迷迷糊糊,沒有經過仔細思考,導致不知從何處開始解決,最後半途而廢。

國內的圈子必然有限,多用google。

附幾個相關問題的連結:

http://www.qtcentre.org/archive/index.php/t-467.html

http://www.qtforum.org/article/18679/qsqlquerymodel-qtableview-and-sorting.html

http://www.qtforum.org/article/26898/how-to-sort-data-by-column-in-a-table-view-model-set-for-table-view-is-qsqlquerymodel-if-click-to-headerview.html

 

轉自:https://www.cnblogs.com/googly/p/4584264.html