如何使用QSortFilterProxyModel对浮点数进行排序?

1 人关注

我有一个使用QSortFilterProxyModel创建表格小部件的类。该类将接受一个字典列表作为数据,然后用字典的关键值填充表格的列和行。当把表格设置为按浮动值排序时,表格中的几个字段变得不可见。然而,当我按字符串值对表进行排序时,就没有问题了。你必须指定类型吗?

按漂浮物排序。 【替换代码0

Sorting by str: self.proxyView.sortByColumn(2, Qt.AscendingOrder)

from PyQt5.QtWidgets import *
from PyQt5.QtCore import (QDate, QDateTime, QRegExp, QSortFilterProxyModel, Qt,
        QTime, QModelIndex, QSize)
from PyQt5.QtGui import QStandardItemModel, QIcon
class Table(QWidget):
    def __init__(self, name, data, columns=None, index=0, parent=None):
        super(Table, self).__init__(parent)
        self.name = name
        #specify which keys of dictionary should be included in the table
        if columns:
            self.columns = columns      
        else:
            self.columns = data[0].keys()
        self.setData(data)
        self.initUI()
    def initUI(self):
        Layout UI elements of table
        mainLayout = QVBoxLayout()
        self.model = QSortFilterProxyModel()
        self.model.setDynamicSortFilter(True)
        model = QStandardItemModel(0, len(self.columns), self)
        for i, column in enumerate(self.columns):
            model.setHeaderData(i, Qt.Horizontal, column)
        self.model.setSourceModel(model)
        self.proxyGroupBox = QGroupBox(self.name)
        self.proxyView = QTreeView()
        self.proxyView.setRootIsDecorated(False)
        self.proxyView.setAlternatingRowColors(True)
        self.proxyView.setModel(self.model)
        self.proxyView.setSortingEnabled(True)
        self.proxyView.setEditTriggers(QAbstractItemView.NoEditTriggers)
        proxyLayout = QGridLayout()
        proxyLayout.addWidget(self.proxyView, 0, 0, 1, 3)
        self.proxyGroupBox.setLayout(proxyLayout)
        mainLayout.addWidget(self.proxyGroupBox)
        self.setLayout(mainLayout)
        self.proxyView.sortByColumn(0, Qt.AscendingOrder)
        self.update(self.data)
        self.show()
    def setSourceModel(self, model):
        self.proxyModel.setSourceModel(model)
    def setData(self, data):
        self.data = [{k: x[k] for k in self.columns} for x in data]
    def setColumns(self, cols):
        self.columns = cols
        self.data = setData()
    def addRow(self, row_i, rowData):
        self.model.insertRow(row_i)
        for col_i, data in enumerate(rowData.values()):
           self.model.setData(self.model.index(row_i, col_i), data)
    def update(self, data):
        self.setData(data)
        self.model.removeRows(0, self.model.rowCount())
        for i, data in enumerate(self.data):
            self.addRow(i, data)
    def getRowIndex(self):
            return self.proxyView.selectedIndexes()[0].row()
        except:
            return False
if __name__=='__main__':
    import sys
    data = [
        {'Lat': 1.123, 'Lon': 12.234, 'Desc': 'Point 1'},
        {'Lat': -2.123, 'Lon': 1.234, 'Desc': 'Point 2'},
        {'Lat': 3.123, 'Lon': -122.234, 'Desc': 'Point 3'},
        {'Lat': -22.123, 'Lon': -31.234, 'Desc': 'Point 4'},
        {'Lat': 33.123, 'Lon': -12.234, 'Desc': 'Point 5'}
    app = QApplication(sys.argv)
    window = Table('Table', data)
    sys.exit(app.exec_())
    
python
pyqt
pyqt5
qsortfilterproxymodel
Evan Brittain
Evan Brittain
发布于 2019-10-10
1 个回答
eyllanesc
eyllanesc
发布于 2019-10-10
已采纳
0 人赞同

Explanation:

问题是,你在proxymodel而不是源模型中添加信息。

为了更好地理解,让我们用下面的例子:假设代理以升序排序,关于第一列,只有2列,并添加了以下数据。 [(2, 1), (1, 2), (-1, 0)]

  • step 1:
  • step 2:
  • step 3:
  • step 4:
  • step 5:
  • step 6:
  • 当一个项目被添加时,它是被排序的,通过添加下一个项目,它可以通过替换之前的值,留下一个空框,而被添加在一个错误的位置。

    Solution:

    为了避免这种情况,你必须将这些信息添加到源模型中,因为这永远不会被重新排列。

    class Table(QWidget):
        # ...
        def initUI(self):
            Layout UI elements of table
            mainLayout = QVBoxLayout()
            self.proxy_model = QSortFilterProxyModel()
            self.proxy_model.setDynamicSortFilter(True)
            self.source_model = QStandardItemModel(0, len(self.columns), self)
            for i, column in enumerate(self.columns):
                self.source_model.setHeaderData(i, Qt.Horizontal, column)
            self.proxy_model.setSourceModel(self.source_model)
            self.proxyGroupBox = QGroupBox(self.name)
            self.proxyView = QTreeView()
            self.proxyView.setRootIsDecorated(False)
            self.proxyView.setAlternatingRowColors(True)
            self.proxyView.setModel(self.proxy_model)
            self.proxyView.setSortingEnabled(True)
            self.proxyView.setEditTriggers(QAbstractItemView.NoEditTriggers)
            proxyLayout = QGridLayout()
            proxyLayout.addWidget(self.proxyView, 0, 0, 1, 3)
            self.proxyGroupBox.setLayout(proxyLayout)
            mainLayout.addWidget(self.proxyGroupBox)
            self.setLayout(mainLayout)
            self.proxyView.sortByColumn(0, Qt.AscendingOrder)
            self.update(self.data)
            self.show()
        def setData(self, data):
            self.data = [{k: x[k] for k in self.columns} for x in data]
        def addRow(self, row_i, rowData):
            self.source_model.insertRow(row_i)
            for col_i, data in enumerate(rowData.values()):
                self.source_model.setData(self.source_model.index(row_i, col_i), data)
        def update(self, data):
            self.setData(data)
            self.source_model.removeRows(0, self.source_model.rowCount())