使用自定义标签时移除QHeaderView的默认列编号
解决QHeaderView自定义跨列标签时默认内容残留问题
你遇到的问题是QHeaderView本身会默认绘制每个列的文本内容,即使设置了空标签,仍会留下绘制痕迹。要在不依赖标签背景覆盖的前提下解决这个问题,只需重写paintSection方法,阻止默认的文本绘制逻辑即可。
修改后的完整代码如下:
import sys from PySide6.QtCore import * from PySide6.QtGui import * from PySide6.QtWidgets import * class CustomHeader(QHeaderView): def __init__(self, orientation, labels, parent=None): QHeaderView.__init__(self, orientation, parent=None) self.sectionResized.connect(self.handleSectionResized) self.label_text = labels self.labels = list() self.setFixedHeight(40) def handleSectionResized(self, i): start = self.visualIndex(i) stop = self.count() for i in range(start, stop): self.labels[i].setGeometry(self.sectionViewportPosition(i), 0, self.sectionSize(i) - 5, self.height()) self.labels[i].show() def showEvent(self, event): for i in range(len(self.label_text)): label = QLabel(self.label_text[i], self) label.setAlignment(Qt.AlignCenter) widget = QWidget(self) vbox = QVBoxLayout() vbox.setSpacing(0) vbox.setContentsMargins(0,0,0,0) vbox.addWidget(label) widget.setLayout(vbox) widget.show() self.labels.append(widget) self.adjustPositions() return super().showEvent(event) def adjustPositions(self): for index, label in enumerate(self.labels): if index == 1 or index == 3: geom = QRect( self.sectionViewportPosition(index), 0, 200, self.height(), ) else: geom = QRect( self.sectionViewportPosition(index), 0, self.sectionSize(index), self.height(), ) geom.adjust(2, 0, -2, 0) label.setGeometry(geom) # 新增重写方法,阻止默认文本绘制 def paintSection(self, painter, rect, logicalIndex): painter.save() # 初始化样式选项并清空文本 option = QStyleOptionHeader() self.initStyleOption(option) option.text = "" # 调用样式绘制表头(仅绘制边框和背景,无文本) self.style().drawControl(QStyle.CE_Header, option, painter, self) painter.restore() class MyTable(QTableWidget): def __init__(self, nrow, ncol, parent=None): super().__init__(nrow, ncol, parent=parent) self.verticalHeader().hide() self.setHorizontalHeaderLabels([]) labels = ['One', 'Two', '', 'Three'] #, 'Four', 'Five'] self.header = CustomHeader(Qt.Horizontal, labels, self) self.setHorizontalHeader(self.header) self.setSelectionBehavior(QAbstractItemView.SelectItems) self.setEditTriggers(QAbstractItemView.NoEditTriggers) data = [ [3, 20, 40, 25, 45], [5, 22, 42, 27, 47], ] for i in range(2): for j in range(5): item = QTableWidgetItem(str(data[i-2][j])) self.setItem(i, j, item) item.setBackground(Qt.white) if __name__ == '__main__': app = QApplication(sys.argv) table = MyTable(7, 5) table.show() sys.exit(app.exec())
关键说明
- 新增的
paintSection方法覆盖了QHeaderView的默认绘制逻辑,通过清空样式选项中的文本,让表头只绘制边框和背景,不再显示默认的列文本。 - 自定义QLabel仍可正常叠加在表头上方,无需设置背景色覆盖原有内容,完美实现跨列标签效果。
内容的提问来源于stack exchange,提问作者mr_js
相关产品推荐
相关产品推荐

