仅对复选框列进行排序

Sort checkbox only columns

这是我当前的代码。

import sys

from PySide6.QtCore import Qt
from PySide6.QtWidgets import (
    QApplication,
    QProxyStyle,
    QStyle,
    QTableWidget,
    QTableWidgetItem,
)


class ProxyStyle(QProxyStyle):
    def subElementRect(self, e, opt, widget):
        r = super().subElementRect(e, opt, widget)
        if e == QStyle.SE_ItemViewItemCheckIndicator:
            r.moveCenter(opt.rect.center())
        return r


class Table(QTableWidget):
    def __init__(self):
        QTableWidget.__init__(self, 3, 1)
        self.setSortingEnabled(True)
        self._style = ProxyStyle(self.style())
        self.setStyle(self._style)
        for i in range(self.rowCount()):
            for j in range(self.columnCount()):
                it = QTableWidgetItem()
                self.setItem(i, j, it)
                it.setFlags(Qt.ItemIsEnabled | Qt.ItemIsUserCheckable)
                it.setCheckState(Qt.Checked if (i + j) % 2 == 0 else Qt.Unchecked)


if __name__ == "__main__":
    app = QApplication(sys.argv)
    w = Table()
    w.show()
    sys.exit(app.exec_())

我希望当您单击 header 列时,复选框会按其状态排序。

如您所见,setSortingEnabled(True) 是不够的。

默认情况下,QTableWidgetItem 使用文本进行比较,因此您可以观察到这种行为,如果您希望它被另一个 属性 排序,那么您必须覆盖 __lt__ 方法:

class CheckboxTableWidgetItem(QTableWidgetItem):
    def __lt__(self, other):
        if self.checkState() == other.checkState():
            return False
        elif self.checkState() == Qt.Checked:
            return False
        return True
for i in range(self.rowCount()):
    for j in range(self.columnCount()):
        <b>it = CheckboxTableWidgetItem()</b>
        self.setItem(i, j, it)
        it.setFlags(Qt.ItemIsEnabled | Qt.ItemIsUserCheckable)
        it.setCheckState(Qt.Checked if (i + j) % 2 == 0 else Qt.Unchecked)