Reputation: 72
I am trying to override QCalendarWidget's paintCell() method to paint a red outline on today's date cell and draw events that will be defined by the user. For my calendar, I used a QItemDelegate to change the alignment of the date flags so I would have more room to draw events. However, I can't seem to get both the QItemDelegate and paintCell() working together. I can only have one or the other work at one time. If I try to do both, only the Delegate shows and nothing is painted.
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, painter, rect, date)
pen = QPen()
pen.setColor(Qt.red)
painter.setPen(pen)
if date == date.currentDate():
painter.save()
painter.drawRect(rect.adjusted(0, 0, -1, -1))
painter.restore()
class CalendarItemDelegate(QItemDelegate):
def paint(self, painter, option, index):
painter._date_flag = index.row() > 0
super().paint(painter, option, index)
def drawDisplay(self, painter, option, rect, text):
if painter._date_flag:
option.displayAlignment = Qt.AlignTop | Qt.AlignLeft
super().drawDisplay(painter, option, rect, text)
app = QApplication(sys.argv)
window = MainWindow()
window.show()
app.exec_()
How can I get both to work at once?
Delegate
PaintCell
Upvotes: 0
Views: 329
Reputation: 48231
When a custom item delegate is set on the calendar widget, the default paintCell
is just ignored, as it's responsibility of the (private) delegate to call it.
Since you're using a QItemDelegate, you can take advantage of the drawFocus()
function and check if the option.state
has the State_Selected
flag set (technically, you could do it in the drawDisplay()
too, since the function is called anyway and the option has the same values):
def drawFocus(self, painter, option, rect):
super().drawFocus(painter, option, rect)
if option.state & QStyle.State_Selected:
painter.save()
painter.setPen(Qt.red)
painter.drawRect(rect.adjusted(0, 0, -1, -1))
painter.restore()
Upvotes: 1