【问题标题】:QTableView: sort by header index -1QTableView:按标题索引排序-1
【发布时间】:2018-09-08 09:44:10
【问题描述】:

我正在使用 PyQt4 并且有一个带有 2 列数据的 QTableView。 索引有一个额外的列(它来自源模型的headerData 函数)。为了在单击标题按钮时进行排序,我用代理类包装了我的模型。

这很好,但我还想通过点击左上角按钮(column number: "-1" I would say)按第一列排序:

根据要求,这是一个最小的示例:

from PyQt4 import QtCore, QtGui
import random, sys

class MyModel(QtCore.QAbstractTableModel):

  headers = 'Name', 'Value'

  def __init__(self, parent=None):
    super(MyModel, self).__init__(parent)

    # Dummy data
    rows = []
    columns = []    
    for i in range(10):
      numbr = random.randint(1,20)
      rows.append('Name #%i' % numbr)
      columns.append('Value #%i' % numbr)
    self.data = zip(rows, columns)

  def columnCount(self, parent=QtCore.QModelIndex()):
    return 2

  def rowCount(self, parent=QtCore.QModelIndex()): 
    return len(self.data)

  def data(self, index, role=QtCore.Qt.DisplayRole):
    if not index.isValid():
      return None

    if (index.row() >= len(self.data)) or (index.row() < 0):
      return None

    if role == QtCore.Qt.DisplayRole or role == QtCore.Qt.EditRole:
      return self.data[index.row()][index.column()]

    return None

  def headerData(self, section, orientation, role):
    if role == QtCore.Qt.DisplayRole :
        if orientation == QtCore.Qt.Horizontal :
            return self.headers[section]
        elif orientation == QtCore.Qt.Vertical :
            return section
    return None

class MyProxyModel(QtGui.QSortFilterProxyModel):
    def __init__(self):
      super(MyProxyModel, self).__init__()

    def lessThan(self, left_index, right_index):
      left_var = left_index.data(QtCore.Qt.EditRole)
      right_var = right_index.data(QtCore.Qt.EditRole)

      # Column #1 (values) should be not sortable
      if left_index.column() == 1: 
        return False

      return left_var < right_var

class MainWindow(QtGui.QMainWindow):
  def __init__(self):
    super(MainWindow, self).__init__()     

    self.model = MyModel()

    self.proxy = MyProxyModel()
    self.proxy.setSourceModel(self.model)
    self.proxy.setFilterKeyColumn(0)

    self.selectionModel = QtGui.QItemSelectionModel(self.proxy)

    self.tableView = QtGui.QTableView()
    self.tableView.setModel(self.proxy)    
    self.tableView.setSelectionModel(self.selectionModel)

    self.tableView.setSortingEnabled(True)
    self.tableView.sortByColumn(0, QtCore.Qt.AscendingOrder)    
    self.setCentralWidget(self.tableView) 

if __name__ == '__main__':
  app = QtGui.QApplication(sys.argv)
  window = MainWindow()
  window.show()
  sys.exit(app.exec_())

有人可以帮帮我吗?

【问题讨论】:

    标签: python pyqt pyqt4 qtableview qsortfilterproxymodel


    【解决方案1】:

    首先,您必须能够获得cornerWidget,它是QAbstractButton,为此我们使用findChild。然后我们使用sort(-1) 使排序无效并将其置于初始状态。

    class MainWindow(QtGui.QMainWindow):
        def __init__(self):
            ...    
            self.setCentralWidget(self.tableView) 
            cornerButton = self.tableView.findChild(QtGui.QAbstractButton)
            cornerButton.clicked.connect(lambda: self.proxy.sort(-1))
    

    【讨论】:

    • 谢谢,这个self.proxy.sort(-1)) 解决方案完美运行并且完全符合它的预期:invalidates the ordering and places it in the initial state。但在我的情况下,垂直标题由工具名称列表组成。它们可能会被重命名,因此当使用角按钮对它们进行排序时,由于它们的初始状态,它们可能会变得不按字母顺序排列。当然,我可以将另一列添加到具有相同名称的主表主体并从那里排序。但是是否可以按角按钮按字母顺序对它们进行排序? Imgur
    猜你喜欢
    • 2018-12-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-30
    • 2016-02-15
    • 2020-04-30
    • 2020-02-07
    • 2018-08-29
    相关资源
    最近更新 更多