在QStandardItem中重载了"<"运算符,但没有被调用

1 投票
1 回答
637 浏览
提问于 2025-04-17 18:50

我有一个用户界面,上面有一个 QTableView,它使用 QStandardItemModel 来存储数据。因为我的一些数据是数字,所以我创建了一个 QStandardItem 的子类,以实现我自己的比较方式。根据文档,我只需要重写 "<" 操作符(也就是 __lt__(...) 函数)。但是,当我点击表格视图中的列标题时,排序并没有正确进行。我的模型填充代码相对简单:

self.model.removeRows(0, self.model.rowCount())
for i in range(0, len(self.mainFlatList)):
   self.model.setItem(i, 0, QStandardItem(self.mainFlatList[str(i)]["ID"]))
   self.model.setItem(i, 1, QStandardItem(self.mainFlatList[str(i)]["type"]))
   self.model.setItem(i, 2, QStandardItem(self.mainFlatList[str(i)]["string1"]))
   self.model.setItem(i, 3, QStandardItem(self.mainFlatList[str(i)]["string2"]))
   self.model.setItem(i, 4, QStandardItem(self.mainFlatList[str(i)]["timeva1"]))
   self.model.setItem(i, 5, QStandardItem(self.mainFlatList[str(i)]["timeval2"]))
   currentOPTimePercent = (float(self.mainFlatList[str(i)]["timeval1"])/self.totalTime) * 100
   self.mainFlatList[str(i)]["timePercent"] = currentOPTimePercent
   self.model.setItem(i, 6, MQStandardItem(str(self.mainFlatList[str(i)]["timePercent"])))

其中 MQStandardItem 只是:

class MQStandardItem(QStandardItem):
def __init__(self, value):
    print "NumericalStandardItem", value
    QStandardItem.__init__(self, value)

def __lt__(self, obj):
    print "Sorting!"
    try:
        return float(self.text()) < float(obj.text())
    except:
        pass

    # Fallback to use standard __lt__
    return self.text() < obj.text()

有没有人知道这可能为什么会失败?我还要提到的是,在 __lt__(...) 函数中的打印语句根本没有被打印出来,这让我怀疑我是否正确地重写了这些东西。如果有帮助的话,这里是我构建用户界面的方法:

    self.model = QStandardItemModel(numRows,numColumns)
    self.model.setHorizontalHeaderItem(0, QStandardItem("ID"))
    self.model.setHorizontalHeaderItem(1, QStandardItem("Type"))
    self.model.setHorizontalHeaderItem(2, QStandardItem("string1"))
    self.model.setHorizontalHeaderItem(3, QStandardItem("string2"))
    self.model.setHorizontalHeaderItem(4, QStandardItem("timeval1"))
    self.model.setHorizontalHeaderItem(5, QStandardItem("timeval2"))
    self.model.setHorizontalHeaderItem(6, QStandardItem("timePercent"))

    self.tableView = QTableView()
    self.tableView.setModel(self.model)
    self.tableView.setSortingEnabled(True)
    self.tableView.setSelectionMode(QAbstractItemView.SingleSelection)
    self.tableView.setSelectionBehavior(QAbstractItemView.SelectRows)
    self.tableView.selectionModel().currentChanged.connect(self.foo)

1 个回答

1

好的,看起来这是Qt的一个bug。之前有个老帖子也在讨论这个问题:

http://www.qtcentre.org/threads/46985-any-solution-to-QtableView-sorting

在查看QTableView类的源代码时,发现视图和模型之间的连接似乎还没有建立,至少从以下链接来看:

http://qt.gitorious.org/qt/qt-gberg/blobs/90cdbf8bd409652fd1e28adcd7f02fc1fae2c1c0/src/gui/itemviews/qtableview.cpp(第2280行)

还有:

http://qt.gitorious.org/qt/qt/blobs/85f42777111060037476895ed08ded513d44a048/src/gui/itemviews/qstandarditemmodel.cpp(第247行)

一个解决办法是使用QTreeWidget,并自己创建一个QTreeWidgetItem类来实现排序。这种方法是可以正常工作的。

撰写回答