使用 QItemDelegate 更改 QCalendarWidget 的日期位置后无法 PaintCell

问题描述

我正在尝试覆盖 QCalendarWidget 的paintCell() 方法以在今天的日期单元格上绘制红色轮廓并绘制将由用户定义的事件。对于我的日历,我使用 QItemDelegate 来更改日期标志的对齐方式,这样我就有更多的空间来绘制事件。但是,我似乎无法让 QItemDelegate 和 paintCell() 一起工作。我一次只能完成一项或另一项工作。如果我尝试同时执行这两项操作,则只会显示 Delegate,而不会绘制任何内容

from pyside2.QtWidgets import QMainWindow,QCalendarWidget,QApplication,QItemDelegate,QTableView
from pyside2.QtGui import QPen
from pyside2.QtCore import Qt
import sys


class MainWindow(QMainWindow):
    def __init__(self,parent=None):
        super().__init__()
        self.calendar = CustomCalendar()
        self.calendarview = self.calendar.findChild(QTableView,"qt_calendar_calendarview")
        self.calendardelegate = CalendarItemDelegate(self.calendarview)
        self.calendarview.setItemDelegate(self.calendardelegate)
        self.setCentralWidget(self.calendar)
        self.show()


class CustomCalendar(QCalendarWidget):
    def __init__(self,parent=None):
        super().__init__()

    def paintCell(self,painter,rect,date):
        QCalendarWidget.paintCell(self,date)
        pen = QPen()
        pen.setColor(Qt.red)
        painter.setPen(pen)
        if date == date.currentDate():
            painter.save()
            painter.drawRect(rect.adjusted(0,-1,-1))
            painter.restore()


class CalendarItemDelegate(QItemDelegate):
    def paint(self,option,index):
        painter._date_flag = index.row() > 0
        super().paint(painter,index)

    def drawdisplay(self,text):
        if painter._date_flag:
            option.displayAlignment = Qt.AlignTop | Qt.AlignLeft
        super().drawdisplay(painter,text)


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

我怎样才能让两者同时工作?

enter image description here

委托

enter image description here

画室

解决方法

在日历小部件上设置自定义项目委托时,默认 paintCell 将被忽略,因为调用它是(私人)委托的责任。

由于您使用的是 QItemDelegate,您可以利用 drawFocus() 函数并检查 option.state 是否设置了 State_Selected 标志(技术上,您可以在drawDisplay() 也是如此,因为无论如何都会调用该函数并且该选项具有相同的值):

    def drawFocus(self,painter,option,rect):
        super().drawFocus(painter,rect)
        if option.state & QStyle.State_Selected:
            painter.save()
            painter.setPen(Qt.red)
            painter.drawRect(rect.adjusted(0,-1,-1))
            painter.restore()