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
相关产品推荐
相关产品推荐

