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

问题描述 投票:0回答:1

我有一个使用QSortFilterProxyModel创建表小部件的类。该类将使用字典列表作为数据,然后用字典的键值填充表的列和行。将表设置为按浮点值排序时,表中的某些字段将变得不可见。但是,当我按字符串值对表进行排序时,没有问题。您必须指定类型吗?

按浮点排序:self.proxyView.sortByColumn(0, Qt.AscendingOrder)

enter image description here

按str排序:self.proxyView.sortByColumn(2, Qt.AscendingOrder)

enter image description here

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):
        try:
            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
1个回答
0
投票

说明:

问题是您将信息添加到代理模型而不是源模型中。

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

  • 步骤1:
2 x
  • 步骤2:
2 1
  • 步骤3:
2 1
1 x
  • 步骤4:
1 x
2 2
  • 步骤5:
 1 x
 2 2
-1 x
  • 步骤6:
-1 x
 1 x
 2 0

[添加项目时,将对其进行排序,并通过添加下一个项目将其替换为错误的位置,方法是替换前一个值并保留一个空白框。

解决方案:

为避免这种情况,您必须将此信息添加到源模型中,因为不会重新排列。

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())

        for i, data in enumerate(self.data):
            self.addRow(i, data)

    # ...
© www.soinside.com 2019 - 2024. All rights reserved.