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

QStyledItemDelegate中drawLine仅在首个Item生效问题求助

问题解决:自定义QStyledItemDelegate仅第一个Item显示平分线条

问题原因

你代码里绘制线条时用了全局坐标系的坐标(QPoint(0, rect.height() // 2)),而非当前Item的局部坐标。只有第一个Item的左上角刚好和viewport原点重合,线条才落在Item可视区域内;其他Item的位置不在这个坐标范围,线条被画到了Item区域外,所以看不到。而绘制矩形时基于option.rect(当前Item的区域)调整,所以所有Item都能正常显示。

解决方案

绘制线条时,基于当前Item的option.rect计算坐标,使用Item区域的左边界、右边界和垂直中线位置:

class CustomDelegate(QStyledItemDelegate):
    def paint(self, painter, option, index):
        painter.setRenderHint(QPainter.Antialiasing)
        rect = option.rect
        
        # 修改后的线条绘制:基于Item的rect计算坐标
        painter.setPen(QPen(QColor("red")))
        # 从Item左边界垂直中线位置,画到右边界垂直中线位置
        painter.drawLine(rect.left(), rect.center().y(), rect.right(), rect.center().y())

        # 矩形绘制保持不变
        painter.setPen(QPen(QColor("black")))
        rect.adjust(20, 20, -20, -20)
        painter.drawRect(rect)

完整可运行代码

from PyQt5.QtWidgets import (QApplication, QWidget, QVBoxLayout, QTableView, 
                             QStyledItemDelegate, QStandardItemModel, QStandardItem)
from PyQt5.QtGui import QPainter, QPen, QColor
from PyQt5.QtCore import QEvent

class CustomDelegate(QStyledItemDelegate):
    def paint(self, painter, option, index):
        painter.setRenderHint(QPainter.Antialiasing)
        rect = option.rect
        
        # 绘制平分Item的红色线条
        painter.setPen(QPen(QColor("red")))
        painter.drawLine(rect.left(), rect.center().y(), rect.right(), rect.center().y())

        # 绘制黑色矩形
        painter.setPen(QPen(QColor("black")))
        rect.adjust(20, 20, -20, -20)
        painter.drawRect(rect)


class CustomTableView(QTableView):
    def __init__(self):
        super().__init__()

        # 创建模型
        model = QStandardItemModel(self)
        model.setHorizontalHeaderLabels(["Column 1", "Column 2", "Column 3"])
        for row in range(3):
            for col in range(3):
                item = QStandardItem(f"Row {row}, Col {col}")
                model.setItem(row, col, item)

        # 创建代理
        delegate = CustomDelegate()

        # 设置模型
        self.setModel(model)

        # 设置代理
        self.setItemDelegate(delegate)

        # 安装事件过滤器
        self.viewport().installEventFilter(self)

    def eventFilter(self, obj, event):
        if event.type() == QEvent.MouseMove:
            print("Mouse moved over the widget at:", event.pos())
        return super().eventFilter(obj, event)


if __name__ == '__main__':
    app = QApplication([])
    window = QWidget()
    layout = QVBoxLayout(window)

    custom_table_view = CustomTableView()
    layout.addWidget(custom_table_view)

    window.show()
    app.exec_()

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.01 06:26:31