绝地无双
您必须创建一个处理编辑器可见性的属性: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()