【问题标题】:PyQt5 Extremely Slow Scrolling on QTableView with pandasPyQt5 使用熊猫在 QTableView 上滚动极慢
【发布时间】:2019-05-19 04:25:57
【问题描述】:

我正在使用 QTableView 在 PyQt5 GUI 内创建一个表。我有来自熊猫数据框的 35 行和 5 列。滚动和排序表格非常慢(大约几秒)。

我已经在寻找解决方案,但大多数人在填充表格时遇到了麻烦。有人建议使用 numpy 数组,但我没有看到性能有任何提升。

这是我的代码:

def create_table(dataframe):
    table = QTableView()
    tm = TableModel(dataframe)
    table.setModel(tm)

    table.setSelectionBehavior(QAbstractItemView.SelectRows)
    table.resizeColumnsToContents()
    table.resizeRowsToContents()
    table.setSortingEnabled(True)

    return table



class TableModel(QtCore.QAbstractTableModel):

    def __init__(self, data, parent=None):
        QtCore.QAbstractTableModel.__init__(self, parent)
        self._data = data

    def rowCount(self, parent=None):
        return len(self._data.values)

    def columnCount(self, parent=None):
        return self._data.columns.size

    def data(self, index, role=QtCore.Qt.DisplayRole):
        if index.isValid():
            if role == QtCore.Qt.DisplayRole:
                return str(self._data.values[index.row()][index.column()])
        return None

    def headerData(self, rowcol, orientation, role):
        if orientation == QtCore.Qt.Horizontal and role == QtCore.Qt.DisplayRole:
            return self._data.columns[rowcol]
        if orientation == QtCore.Qt.Vertical and role == QtCore.Qt.DisplayRole:
            return self._data.index[rowcol]
        return None

    def flags(self, index):
        flags = super(self.__class__, self).flags(index)
        flags |= QtCore.Qt.ItemIsEditable
        flags |= QtCore.Qt.ItemIsSelectable
        flags |= QtCore.Qt.ItemIsEnabled
        flags |= QtCore.Qt.ItemIsDragEnabled
        flags |= QtCore.Qt.ItemIsDropEnabled
        return flags

    def sort(self, Ncol, order):
        """Sort table by given column number.
        """
        try:
            self.layoutAboutToBeChanged.emit()
            self._data = self._data.sort_values(self._data.columns[Ncol], ascending=not order)
            self.layoutChanged.emit()
        except Exception as e:
            print(e)


table = create_table(dataframe)

我在这里发现了一个问题Slow scrolling with QTableView on other comp,用户有类似的问题,他/她发现“QTableView is refresh the items at each scroll/appearance,这显然是来源的问题。”但是我不知道我的桌子是否和那张桌子有同样的问题。

如何使表格的滚动和排序更快?问题的根源是什么?

【问题讨论】:

  • 您的dataflags 方法可以轻松优化,但首先您应该收集客观的性能数据。试试python -m cProfile -s cumtime your_main_file.py > profile.txt
  • 你可以分享你的数据,除了改善你的 MCVE 之外,我没有观察到这种行为
  • 尝试将return len(self._data.values)更改为return len(self._data.index)
  • return str(self._data.values[index.row()][index.column()])return str(self._data.iloc[index.row(), index.column()])
  • @eyllanesc 这些更改效果很好

标签: python pandas pyqt pyqt5 qtableview


【解决方案1】:

问题在于 rowCount 和 data 方法,因为您没有使用最好的函数。在使用值时使用 rowCount 的情况下,您正在创建一个消耗时间的新数据,在这种情况下使用索引。和数据一样,你必须使用iloc():

def rowCount(self, parent=None):
    return len(self._data.index)

# ...

def data(self, index, role=QtCore.Qt.DisplayRole):
    if index.isValid():
        if role == QtCore.Qt.DisplayRole:
            return str(self._data.iloc[index.row(), index.column()])
    return None

【讨论】:

  • 完美运行!
  • @KenBassett 我也在使用类似的模型,他们向我传递了超过 1000 行的数据,我遇到了类似的问题,我意识到问题就是这样。 :-)
猜你喜欢
  • 2020-07-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-07-30
  • 1970-01-01
  • 1970-01-01
  • 2020-06-08
  • 1970-01-01
相关资源
最近更新 更多