You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用自定义标签时移除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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.31 20:46:34