I try to make a corner in the cells of my QCalendarWidget. So I made a QItemDelegate in which I draw my triangle.
As the screenshot shows, the delegate works fine on the first column, but is completely broken on the others.
I don't understand where this comes from (I'm new to Qt, so maybe I did something wrong).
Here is the code:
# ---------------------------------
# ------ CalendarDayDelegate ------
class CalendarDayDelegate(QItemDelegate):
def __init__(self, parent=None, projects=None):
super(CalendarDayDelegate, self).__init__(parent=parent)
self.projects = projects
def paint(self, painter, option, index):
painter._date_flag = index.row() > 0
super(CalendarDayDelegate, self).paint(painter, option, index)
if painter._date_flag:
rect = option.rect
corner = QPolygon([
rect.topRight(),
QPoint(rect.center().x() + (rect.center().x() / 2), rect.top()),
QPoint(rect.bottomRight().x(), rect.center().y())
])
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 painter._date_flag:
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._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)
And the screenshot
The issue is with the second point of the polygon: since you're setting it based on the x
of the center, every new column of the table will have a different coordinate reference.
If you just print the rect, you'll see the result:
def paint(self, painter, option, index):
# ...
if index.row() == 1:
print(index.column(), rect.center())
Which will output:
>>> 0 PyQt5.QtCore.QPoint(15, 41)
>>> 1 PyQt5.QtCore.QPoint(46, 41)
>>> 2 PyQt5.QtCore.QPoint(77, 41)
>>> 3 PyQt5.QtCore.QPoint(108, 41)
>>> 4 PyQt5.QtCore.QPoint(139, 41)
Since you're adding half of the "center x
" coordinate everytime, the result is that the second point gets far and far away everytime you get a new rectangle based on a non-zero column.
If you want that corner to start at 75% of the rect width, just use a the top right corner as a reference, and then subtract/add relative coordinates (QPoint) from/to it:
ref = rect.topRight()
corner = QPolygon([
ref,
ref + QPoint(-rect.width() / 4, 0),
ref + QPoint(0, rect.height() / 2)
])