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