按字母顺序对 QTreeWidget 进行排序,除了一项

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

我有一个带有项目的 QTreeWidget。我用它来提供“全选”选项的项目之一。

我想将“全选”项目固定在顶部,然后按字母顺序对下面的所有其他项目进行排序。 我尝试为“全选”项目创建一个角色,以表明该项目必须始终位于最上面。因此,每当启用 Skip_sorting 时,我都会重写 lt 方法以返回 False,否则按字母顺序排序(请参阅下面的代码)。 我遇到的问题是,如果我打印称为(

print(self.text(column), other.text(column))
)的比较,self 始终是“全选”项目,但我看不到其他项目之间的比较。我正在使用 pyside6 6.3.2

class TreeWidgetItem(QTreeWidgetItem):
    """
    Sort items alphabetically but exclude the "Select All" on top
    """

    def __lt__(self, other):
        column = self.treeWidget().sortColumn()
        print(self.text(column), other.text(column))

        skip_sorting_self = self.data(column, _SKIP_SORT_ROLE)
        skip_sorting_other = other.data(column, _SKIP_SORT_ROLE)

        if skip_sorting_self and not skip_sorting_other:
            return False

        return self.text(column).lower() < other.text(column).lower()

enter image description here


更新

这里有一个失败的示例:

import sys
from typing import Optional

from PySide6.QtCore import Qt
from PySide6.QtWidgets import QApplication, QTreeWidget, QTreeWidgetItem, QWidget

_SKIP_SORT_ROLE: int = (Qt.UserRole + 4)


class TreeWidgetItem(QTreeWidgetItem):
    """
    Sort items alphabetically but exclude the Select All
    """

    def __lt__(self, other):
        column = self.treeWidget().sortColumn()

        skip_sorting_self = self.data(column, _SKIP_SORT_ROLE)
        text = self.text(column)
        if skip_sorting_self:
            text = ''  # lowest possible

        return text > other.text(column).lower()


class TreeWidget(QTreeWidget):

    def __init__(self, parent: Optional[QWidget] = None):
        super(TreeWidget, self).__init__(parent)

        item = TreeWidgetItem(self)
        item.setText(0, 'Select All')
        item.setData(0, _SKIP_SORT_ROLE, True)

        for i in range(10):
            item = TreeWidgetItem(self)
            item.setText(0, f'Item {i}')

        for i in range(10):
            item = TreeWidgetItem(self)
            item.setText(0, f'Item {i}')

        self.setSortingEnabled(True)


if __name__ == '__main__':
    app = QApplication(sys.argv)
    tree = TreeWidget()
    tree.show()
    sys.exit(app.exec())

看截图:

enter image description here

python qt sorting pyside6 qtreewidget
1个回答
0
投票

这里的问题是初始排序顺序。对于树形小部件,这是由标题决定的,标题意外地默认为“降序”。因此,假设您想要升序,您需要在启用排序之前重置它,并相应地调整__lt__的实现 - 像这样:

import sys
from PySide6.QtCore import Qt
from PySide6.QtWidgets import QApplication, QTreeWidget, QTreeWidgetItem, QWidget

_SKIP_SORT_ROLE: int = (Qt.UserRole + 4)

class TreeWidgetItem(QTreeWidgetItem):
    def __lt__(self, other):
        column = self.treeWidget().sortColumn()
        if self.data(column, _SKIP_SORT_ROLE):
            return True
        return self.text(column).lower() < other.text(column).lower()

class TreeWidget(QTreeWidget):
    def __init__(self, parent=None):
        super(TreeWidget, self).__init__(parent)
        item = TreeWidgetItem(self)
        item.setText(0, 'Select All')
        item.setData(0, _SKIP_SORT_ROLE, True)
        for i in range(3):
            item = TreeWidgetItem(self)
            item.setText(0, f'Item {i}')
        for i in range(3):
            item = TreeWidgetItem(self)
            item.setText(0, f'Item {i}')
        self.sortByColumn(self.sortColumn(), Qt.AscendingOrder)
        self.setSortingEnabled(True)

if __name__ == '__main__':

    app = QApplication(sys.argv)
    tree = TreeWidget()
    tree.show()
    sys.exit(app.exec())

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