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

如何为PyQt5 QTableView表头设置两行不同字体的文本?

实现QTableView表头两行不同样式文本

问题背景

当前运行代码后的表头仅能显示普通换行文本,无法区分字号与粗细;期望实现水平表头每个单元格显示两行居中文本:上行使用较大字号,下行使用较小字号且为粗体。

尝试过HTML和QCSS样式,但Qt表头不支持该方式,需通过实现QStyledItemDelegate并绑定到QHeaderView来实现。此前代码错误地将Delegate设置给了表格列(仅修改数据单元格),未作用于表头。

解决方案

核心步骤:

  • 自定义QStyledItemDelegate,在paint方法中手动绘制两行不同样式的文本
  • 将自定义Delegate绑定到表格的水平表头(而非表格列)
  • 调整表头高度以适配两行文本显示

以下是修改后的完整代码:

# base of example from https://www.pythonguis.com/tutorials/qtableview-modelviews-numpy-pandas/
import sys
from PyQt5 import QtCore, QtGui, QtWidgets
from PyQt5.QtCore import Qt, QTimer
from PyQt5.QtWidgets import QStyledItemDelegate

coltxts = {
  0: "STANDARD_COLUMN_DESCRIPTION",
  1: "ADVANCED_COLUMN_DESCRIPTION",
  2: "VERBOSE_COLUMN_DESCRIPTION",
}

class TableModel(QtCore.QAbstractTableModel):
  def __init__(self, data):
    super(TableModel, self).__init__()
    self._data = data

  def data(self, index, role):
    if role == Qt.DisplayRole:
      return self._data[index.row()][index.column()]

  def headerData(self, section, orientation, role=Qt.DisplayRole):
    if orientation == Qt.Horizontal:
      if role == Qt.DisplayRole:
        # 返回元组存储两行文本内容
        return ("Column {}".format(section), coltxts[section])
    return super().headerData(section, orientation, role)

  def rowCount(self, index):
    return len(self._data)

  def columnCount(self, index):
    return len(self._data[0])


class MainWindow(QtWidgets.QMainWindow):
  def __init__(self):
    super().__init__()

    self.table = QtWidgets.QTableView()

    data = [
      [4, 9, 2],
      [1, 0, 0],
      [3, 5, 0],
      [3, 3, 2],
      [7, 8, 9],
    ]

    self.model = TableModel(data)
    self.table.setModel(self.model)

    # 给水平表头设置自定义Delegate
    header_delegate = TwoLineHeaderDelegate(self.table)
    self.table.horizontalHeader().setItemDelegate(header_delegate)
    
    # 设置表头高度以适配两行文本
    self.table.horizontalHeader().setMinimumHeight(60)
    # 自动调整列宽
    QTimer.singleShot(10, self.table.resizeColumnsToContents)
    
    self.setCentralWidget(self.table)


class TwoLineHeaderDelegate(QStyledItemDelegate):
  def paint(self, painter, option, index):
    # 获取表头的两行文本内容
    header_text = index.data(Qt.DisplayRole)
    if not isinstance(header_text, tuple) or len(header_text) !=2:
      super().paint(painter, option, index)
      return
    
    top_text, bottom_text = header_text
    
    # 保存 painter 状态,避免影响后续绘制
    painter.save()
    
    # 设置绘制区域为表头单元格范围
    painter.setClipRect(option.rect)
    
    # 绘制背景(保持原表头样式)
    if option.state & QtWidgets.QStyle.State_Selected:
      painter.fillRect(option.rect, option.palette.highlight())
    
    # ------------------- 绘制上行文本(大字号) -------------------
    top_font = painter.font()
    top_font.setPointSize(top_font.pointSize() + 2)  # 增大字号
    painter.setFont(top_font)
    
    # 计算上行文本的绘制位置(居中)
    top_rect = QtCore.QRect(option.rect)
    top_rect.setHeight(option.rect.height() // 2)
    painter.drawText(top_rect, Qt.AlignCenter, top_text)
    
    # ------------------- 绘制下行文本(小字号+粗体) -------------------
    bottom_font = painter.font()
    bottom_font.setPointSize(bottom_font.pointSize() - 2)  # 减小字号
    bottom_font.setBold(True)  # 设置粗体
    painter.setFont(bottom_font)
    
    # 计算下行文本的绘制位置(居中)
    bottom_rect = QtCore.QRect(option.rect)
    bottom_rect.setTop(option.rect.top() + option.rect.height() // 2)
    painter.drawText(bottom_rect, Qt.AlignCenter, bottom_text)
    
    # 恢复 painter 状态
    painter.restore()

  def sizeHint(self, option, index):
    # 自定义表头单元格的大小提示,确保能放下两行文本
    hint = super().sizeHint(option, index)
    hint.setHeight(max(hint.height(), 60))
    return hint


app=QtWidgets.QApplication(sys.argv)
window=MainWindow()
window.show()
app.exec_()

代码说明

  1. Model修改:headerData返回包含两行文本的元组,方便Delegate获取内容
  2. 自定义Delegate:
    • 在paint方法中分别绘制两行文本,设置不同的字体属性(字号、粗细)
    • 手动计算每行文本的绘制区域,确保居中对齐
    • 保留原表头的选中状态绘制逻辑,保持样式一致性
  3. 表头绑定:通过self.table.horizontalHeader().setItemDelegate()将Delegate绑定到水平表头
  4. 尺寸调整:设置表头最小高度,确保两行文本完全显示

内容的提问来源于stack exchange,提问作者sdbbs

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.25 13:30:54