为了账号安全,请及时绑定邮箱和手机立即绑定

如何使用按钮启用和禁用 QHeaderView 过滤器

如何使用按钮启用和禁用 QHeaderView 过滤器

qq_遁去的一_1 2023-07-11 17:09:56
我想首先有一个在 QHeaderView 下面没有过滤器的普通视图和一个用于激活(显示)过滤器的按钮:单击“过滤器”按钮(具有属性“button.setCheckable(True)”)后,我想得到:注意:过滤器按钮被按下。现在,当我再次单击“过滤器”按钮(取消按下它)时,我希望 QHeaderView 下面带有过滤器的行消失:我该怎么做,换句话说,如何让 QTableView 的 QHeaderView 成为旧的普通视图?在应用程序中拥有这种功能将非常方便,用户可以随时使用按钮(或任何其他方式)切换 QHeaderView 下面的过滤器行。应用程序的行为是在未按下按钮并且过滤器行消失时取消视图中的所有过滤器,但这对于这个问题并不重要。
查看完整描述

1 回答

?
绝地无双

TA贡献1946条经验 获得超4个赞

您必须创建一个处理编辑器可见性的属性:


class FilterHeader(QHeaderView):

    filterActivated = pyqtSignal()


    def __init__(self, parent):

        super().__init__(Qt.Horizontal, parent)

        self._visible_editors = False

        self._editors = []

        self._padding = 4

        self.setStretchLastSection(True)

        # self.setResizeMode(QHeaderView.Stretch)

        self.setDefaultAlignment(Qt.AlignLeft | Qt.AlignVCenter)

        self.setSortIndicatorShown(False)

        self.sectionResized.connect(self.adjustPositions)

        parent.horizontalScrollBar().valueChanged.connect(self.adjustPositions)


    @property

    def visible_editors(self):

        return self._visible_editors


    @visible_editors.setter

    def visible_editors(self, is_visible):

        self._visible_editors = is_visible

        for editor in self._editors:

            editor.setVisible(self.visible_editors)

        self.updateGeometries()


    def setFilterBoxes(self, count):

        while self._editors:

            editor = self._editors.pop()

            editor.deleteLater()

        for index in range(count):

            editor = self.create_editor(self.parent(), index)

            editor.setVisible(self.visible_editors)

            self._editors.append(editor)

        self.adjustPositions()


    def create_editor(self, parent, index):

        if index == 1:  # Empty

            editor = QWidget()

        elif index == 2:  # Number filter (>|=|<)

            editor = Widget(parent)

            editor.linee.returnPressed.connect(self.filterActivated)

            editor.btn.clicked.connect(self.changebuttonsymbol)

        elif index == 3:

            editor = QComboBox(parent)

            editor.addItems(["", "Combo", "One", "Two", "Three"])

            editor.currentIndexChanged.connect(self.filterActivated)

        elif index == 4:

            editor = QPushButton(parent)

            editor.clicked.connect(self.filterActivated)

            editor.setText("Button")

        elif index == 5:

            editor = QCheckBox(parent)

            editor.clicked.connect(self.filterActivated)

            editor.setTristate(True)

            editor.setCheckState(Qt.Checked)

            editor.setText("CheckBox")

        else:

            editor = QLineEdit(parent)

            editor.setPlaceholderText("Filter")

            editor.returnPressed.connect(self.filterActivated)

        return editor


    def sizeHint(self):

        size = super().sizeHint()

        if self._editors and self.visible_editors:

            height = self._editors[0].sizeHint().height()

            size.setHeight(size.height() + height + self._padding)

        return size


    def updateGeometries(self):

        if self._editors and self.visible_editors:

            height = self._editors[0].sizeHint().height()

            self.setViewportMargins(0, 0, 0, height + self._padding)

        else:

            self.setViewportMargins(0, 0, 0, 0)

        super().updateGeometries()

        self.adjustPositions()


    def adjustPositions(self):

        for index, editor in enumerate(self._editors):

            if not isinstance(editor, QWidget):

                continue

            height = editor.sizeHint().height()

            compensate_y = 0

            compensate_x = 0

            if type(editor) is QComboBox:

                compensate_y = +2

            elif type(editor) in (QWidget, Widget):

                compensate_y = -1

            elif type(editor) is QPushButton:

                compensate_y = -1

            elif type(editor) is QCheckBox:

                compensate_y = 4

                compensate_x = 4

            editor.move(

                self.sectionPosition(index) - self.offset() + 1 + compensate_x,

                height + (self._padding // 2) + 2 + compensate_y,

            )

            editor.resize(self.sectionSize(index), height)


    def filterText(self, index):

        for editor in self._editors:

            if hasattr(editor, "text") and callable(editor.text):

                return editor.text()

        return ""


    def setFilterText(self, index, text):

        for editor in self._editors:

            if hasattr(editor, "setText") and callable(editor.setText):

                editor.setText(text)


    def clearFilters(self):

        for editor in self._editors:

            editor.clear()


    def changebuttonsymbol(self):

        nbtn = self.sender()

        if nbtn.text() == "=":

            nbtn.setText(">")

        elif nbtn.text() == ">":

            nbtn.setText("<")

        else:

            nbtn.setText("=")



class Window(QWidget):

    def __init__(self):

        super(Window, self).__init__()

        self.filter_button = QPushButton("Filter")

        self.filter_button.setCheckable(True)

        self.filter_button.setChecked(True)

        self.filter_button.clicked.connect(self.on_button_clicked)

        self.view = QTableView()

        self.view.horizontalHeader().setStretchLastSection(True)


        button_layout = QHBoxLayout()

        button_layout.addStretch()

        button_layout.addWidget(self.filter_button)


        layout = QVBoxLayout(self)

        layout.addLayout(button_layout)

        layout.addWidget(self.view)


        header = FilterHeader(self.view)

        self.view.setHorizontalHeader(header)

        self.view.verticalHeader().setVisible(False)

        # model = QStandardItemModel(self.view)

        model = QStandardItemModel(5, 7, self.view)

        for i in range(5):

            for j in range(7):

                item = QStandardItem(str(i + j))

                model.setItem(i, j, item)

        model.setHorizontalHeaderLabels("One Two Three Four Five Six Seven".split())

        self.view.setModel(model)

        header.setFilterBoxes(model.columnCount())

        header.filterActivated.connect(self.handleFilterActivated)


        self.on_button_clicked()


    def handleFilterActivated(self):

        header = self.view.horizontalHeader()

        for index in range(header.count()):

            if index != 4:

                print(index, header.filterText(index))

            else:

                print("Button")


    def on_button_clicked(self):

        self.view.horizontalHeader().visible_editors = self.filter_button.isChecked()



查看完整回答
反对 回复 2023-07-11
  • 1 回答
  • 0 关注
  • 76 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信