QCalendarWidget中QItemDelegate跨列渲染效果不一致问题求助
问题根源
你自定义委托绘制异常的核心原因是三角形顶点坐标计算逻辑错误:option.rect保存的是单元格在日历表格视图中的全局位置,而非单元格内部的相对坐标,你直接使用全局的center.x()计算顶点,第一列单元格x轴偏移量小,计算结果刚好落在单元格范围内;越靠右的列x轴偏移量越大,计算出的顶点会直接溢出单元格,因此显示异常。
修复后的代码
仅需修改CalendarDayDelegate的坐标计算逻辑即可:
# --------------------------------- # ------ CalendarDayDelegate ------ class CalendarDayDelegate(QItemDelegate): def __init__(self, parent=None, projects=None): super(CalendarDayDelegate, self).__init__(parent=parent) self.projects = projects # 可自定义角标大小,也可以用rect.width()*0.2这类比例实现自适应 self.corner_size = 15 def paint(self, painter, option, index): painter._date_flag = index.row() > 0 super(CalendarDayDelegate, self).paint(painter, option, index) if not painter._date_flag: return rect = option.rect # 基于单元格边界计算右上角三角形坐标,适配所有列 corner = QPolygon([ rect.topRight(), QPoint(rect.right() - self.corner_size, rect.top()), QPoint(rect.right(), rect.top() + self.corner_size) ]) painter.save() painter.setRenderHint(painter.Antialiasing) painter.setBrush(QBrush(QColor(Qt.darkGreen))) painter.setPen(QPen(QColor(Qt.darkGreen))) painter.drawPolygon(corner) painter.restore() def drawDisplay(self, painter, option, rect, text): if getattr(painter, '_date_flag', False): option.displayAlignment = Qt.AlignTop | Qt.AlignLeft super(CalendarDayDelegate, self).drawDisplay(painter, option, rect, text) # ---------------------- # ------ Calendar ------ class MonthReviewCalendar(QCalendarWidget): def __init__(self, parent=None): super(MonthReviewCalendar, self).__init__(parent=parent) # 补充你自己的项目数据初始化逻辑即可 self._raw_projects = [] self._init_calendar() def _init_calendar(self): self.setVerticalHeaderFormat( self.verticalHeaderFormat().NoVerticalHeader ) self.setFirstDayOfWeek(Qt.Monday) self.calendar_view = self.findChild( QTableView, "qt_calendar_calendarview" ) self.calendar_delegate = CalendarDayDelegate( projects=self._raw_projects ) self.calendar_view.setItemDelegate(self.calendar_delegate)
内容的提问来源于stack exchange,提问作者Pixidream
相关产品推荐
相关产品推荐

