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

我想首先有一个在 QHeaderView 下面没有过滤器的普通视图和一个用于激活(显示)过滤器的按钮:

http://img3.sycdn.imooc.com/64ad1c8200015c6306490171.jpg

单击“过滤器”按钮(具有属性“button.setCheckable(True)”)后,我想得到:

http://img4.sycdn.imooc.com/64ad1c8f00011df806500170.jpg

注意:过滤器按钮被按下。现在,当我再次单击“过滤器”按钮(取消按下它)时,我希望 QHeaderView 下面带有过滤器的行消失:

http://img4.sycdn.imooc.com/64ad1c9d0001cb9606510176.jpg

我该怎么做,换句话说,如何让 QTableView 的 QHeaderView 成为旧的普通视图?在应用程序中拥有这种功能将非常方便,用户可以随时使用按钮(或任何其他方式)切换 QHeaderView 下面的过滤器行。应用程序的行为是在未按下按钮并且过滤器行消失时取消视图中的所有过滤器,但这对于这个问题并不重要。




qq_遁去的一_1
浏览 112回答 1
1回答

绝地无双

您必须创建一个处理编辑器可见性的属性:class FilterHeader(QHeaderView):&nbsp; &nbsp; filterActivated = pyqtSignal()&nbsp; &nbsp; def __init__(self, parent):&nbsp; &nbsp; &nbsp; &nbsp; super().__init__(Qt.Horizontal, parent)&nbsp; &nbsp; &nbsp; &nbsp; self._visible_editors = False&nbsp; &nbsp; &nbsp; &nbsp; self._editors = []&nbsp; &nbsp; &nbsp; &nbsp; self._padding = 4&nbsp; &nbsp; &nbsp; &nbsp; self.setStretchLastSection(True)&nbsp; &nbsp; &nbsp; &nbsp; # self.setResizeMode(QHeaderView.Stretch)&nbsp; &nbsp; &nbsp; &nbsp; self.setDefaultAlignment(Qt.AlignLeft | Qt.AlignVCenter)&nbsp; &nbsp; &nbsp; &nbsp; self.setSortIndicatorShown(False)&nbsp; &nbsp; &nbsp; &nbsp; self.sectionResized.connect(self.adjustPositions)&nbsp; &nbsp; &nbsp; &nbsp; parent.horizontalScrollBar().valueChanged.connect(self.adjustPositions)&nbsp; &nbsp; @property&nbsp; &nbsp; def visible_editors(self):&nbsp; &nbsp; &nbsp; &nbsp; return self._visible_editors&nbsp; &nbsp; @visible_editors.setter&nbsp; &nbsp; def visible_editors(self, is_visible):&nbsp; &nbsp; &nbsp; &nbsp; self._visible_editors = is_visible&nbsp; &nbsp; &nbsp; &nbsp; for editor in self._editors:&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; editor.setVisible(self.visible_editors)&nbsp; &nbsp; &nbsp; &nbsp; self.updateGeometries()&nbsp; &nbsp; def setFilterBoxes(self, count):&nbsp; &nbsp; &nbsp; &nbsp; while self._editors:&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; editor = self._editors.pop()&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; editor.deleteLater()&nbsp; &nbsp; &nbsp; &nbsp; for index in range(count):&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; editor = self.create_editor(self.parent(), index)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; editor.setVisible(self.visible_editors)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; self._editors.append(editor)&nbsp; &nbsp; &nbsp; &nbsp; self.adjustPositions()&nbsp; &nbsp; def create_editor(self, parent, index):&nbsp; &nbsp; &nbsp; &nbsp; if index == 1:&nbsp; # Empty&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; editor = QWidget()&nbsp; &nbsp; &nbsp; &nbsp; elif index == 2:&nbsp; # Number filter (>|=|<)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; editor = Widget(parent)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; editor.linee.returnPressed.connect(self.filterActivated)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; editor.btn.clicked.connect(self.changebuttonsymbol)&nbsp; &nbsp; &nbsp; &nbsp; elif index == 3:&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; editor = QComboBox(parent)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; editor.addItems(["", "Combo", "One", "Two", "Three"])&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; editor.currentIndexChanged.connect(self.filterActivated)&nbsp; &nbsp; &nbsp; &nbsp; elif index == 4:&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; editor = QPushButton(parent)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; editor.clicked.connect(self.filterActivated)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; editor.setText("Button")&nbsp; &nbsp; &nbsp; &nbsp; elif index == 5:&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; editor = QCheckBox(parent)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; editor.clicked.connect(self.filterActivated)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; editor.setTristate(True)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; editor.setCheckState(Qt.Checked)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; editor.setText("CheckBox")&nbsp; &nbsp; &nbsp; &nbsp; else:&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; editor = QLineEdit(parent)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; editor.setPlaceholderText("Filter")&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; editor.returnPressed.connect(self.filterActivated)&nbsp; &nbsp; &nbsp; &nbsp; return editor&nbsp; &nbsp; def sizeHint(self):&nbsp; &nbsp; &nbsp; &nbsp; size = super().sizeHint()&nbsp; &nbsp; &nbsp; &nbsp; if self._editors and self.visible_editors:&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; height = self._editors[0].sizeHint().height()&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; size.setHeight(size.height() + height + self._padding)&nbsp; &nbsp; &nbsp; &nbsp; return size&nbsp; &nbsp; def updateGeometries(self):&nbsp; &nbsp; &nbsp; &nbsp; if self._editors and self.visible_editors:&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; height = self._editors[0].sizeHint().height()&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; self.setViewportMargins(0, 0, 0, height + self._padding)&nbsp; &nbsp; &nbsp; &nbsp; else:&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; self.setViewportMargins(0, 0, 0, 0)&nbsp; &nbsp; &nbsp; &nbsp; super().updateGeometries()&nbsp; &nbsp; &nbsp; &nbsp; self.adjustPositions()&nbsp; &nbsp; def adjustPositions(self):&nbsp; &nbsp; &nbsp; &nbsp; for index, editor in enumerate(self._editors):&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if not isinstance(editor, QWidget):&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; continue&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; height = editor.sizeHint().height()&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; compensate_y = 0&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; compensate_x = 0&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if type(editor) is QComboBox:&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; compensate_y = +2&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; elif type(editor) in (QWidget, Widget):&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; compensate_y = -1&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; elif type(editor) is QPushButton:&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; compensate_y = -1&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; elif type(editor) is QCheckBox:&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; compensate_y = 4&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; compensate_x = 4&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; editor.move(&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; self.sectionPosition(index) - self.offset() + 1 + compensate_x,&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; height + (self._padding // 2) + 2 + compensate_y,&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; )&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; editor.resize(self.sectionSize(index), height)&nbsp; &nbsp; def filterText(self, index):&nbsp; &nbsp; &nbsp; &nbsp; for editor in self._editors:&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if hasattr(editor, "text") and callable(editor.text):&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return editor.text()&nbsp; &nbsp; &nbsp; &nbsp; return ""&nbsp; &nbsp; def setFilterText(self, index, text):&nbsp; &nbsp; &nbsp; &nbsp; for editor in self._editors:&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if hasattr(editor, "setText") and callable(editor.setText):&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; editor.setText(text)&nbsp; &nbsp; def clearFilters(self):&nbsp; &nbsp; &nbsp; &nbsp; for editor in self._editors:&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; editor.clear()&nbsp; &nbsp; def changebuttonsymbol(self):&nbsp; &nbsp; &nbsp; &nbsp; nbtn = self.sender()&nbsp; &nbsp; &nbsp; &nbsp; if nbtn.text() == "=":&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; nbtn.setText(">")&nbsp; &nbsp; &nbsp; &nbsp; elif nbtn.text() == ">":&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; nbtn.setText("<")&nbsp; &nbsp; &nbsp; &nbsp; else:&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; nbtn.setText("=")class Window(QWidget):&nbsp; &nbsp; def __init__(self):&nbsp; &nbsp; &nbsp; &nbsp; super(Window, self).__init__()&nbsp; &nbsp; &nbsp; &nbsp; self.filter_button = QPushButton("Filter")&nbsp; &nbsp; &nbsp; &nbsp; self.filter_button.setCheckable(True)&nbsp; &nbsp; &nbsp; &nbsp; self.filter_button.setChecked(True)&nbsp; &nbsp; &nbsp; &nbsp; self.filter_button.clicked.connect(self.on_button_clicked)&nbsp; &nbsp; &nbsp; &nbsp; self.view = QTableView()&nbsp; &nbsp; &nbsp; &nbsp; self.view.horizontalHeader().setStretchLastSection(True)&nbsp; &nbsp; &nbsp; &nbsp; button_layout = QHBoxLayout()&nbsp; &nbsp; &nbsp; &nbsp; button_layout.addStretch()&nbsp; &nbsp; &nbsp; &nbsp; button_layout.addWidget(self.filter_button)&nbsp; &nbsp; &nbsp; &nbsp; layout = QVBoxLayout(self)&nbsp; &nbsp; &nbsp; &nbsp; layout.addLayout(button_layout)&nbsp; &nbsp; &nbsp; &nbsp; layout.addWidget(self.view)&nbsp; &nbsp; &nbsp; &nbsp; header = FilterHeader(self.view)&nbsp; &nbsp; &nbsp; &nbsp; self.view.setHorizontalHeader(header)&nbsp; &nbsp; &nbsp; &nbsp; self.view.verticalHeader().setVisible(False)&nbsp; &nbsp; &nbsp; &nbsp; # model = QStandardItemModel(self.view)&nbsp; &nbsp; &nbsp; &nbsp; model = QStandardItemModel(5, 7, self.view)&nbsp; &nbsp; &nbsp; &nbsp; for i in range(5):&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; for j in range(7):&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; item = QStandardItem(str(i + j))&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; model.setItem(i, j, item)&nbsp; &nbsp; &nbsp; &nbsp; model.setHorizontalHeaderLabels("One Two Three Four Five Six Seven".split())&nbsp; &nbsp; &nbsp; &nbsp; self.view.setModel(model)&nbsp; &nbsp; &nbsp; &nbsp; header.setFilterBoxes(model.columnCount())&nbsp; &nbsp; &nbsp; &nbsp; header.filterActivated.connect(self.handleFilterActivated)&nbsp; &nbsp; &nbsp; &nbsp; self.on_button_clicked()&nbsp; &nbsp; def handleFilterActivated(self):&nbsp; &nbsp; &nbsp; &nbsp; header = self.view.horizontalHeader()&nbsp; &nbsp; &nbsp; &nbsp; for index in range(header.count()):&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if index != 4:&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; print(index, header.filterText(index))&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; else:&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; print("Button")&nbsp; &nbsp; def on_button_clicked(self):&nbsp; &nbsp; &nbsp; &nbsp; self.view.horizontalHeader().visible_editors = self.filter_button.isChecked()
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Python