Skip to content Skip to sidebar Skip to footer

Adding Items To A Qtableview Within Qcalendarwidget

I'm currently making a to-do application which has a calendar. Whenever the user has an event on a specific date, A red circle appears in the top left corner. Whenever the user dou

Solution 1:

Instead of storing in some event by date another approach is to get the date given the row and column, and then filter the events.

The problem is that there is no public method to calculate the date given the row and column, so my solution uses the Qt private API code.

Considering the above, the solution is:

import random
from dataclasses import dataclassfrom PyQt5 import QtCore, QtGui, QtWidgets


@dataclassclassTodo:
    date: QtCore.QDate
    name: strclassTodoCalendar(QtWidgets.QCalendarWidget):
    def__init__(self, list_of_events, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.list_of_events = list_of_events

        self.table = self.findChild(QtWidgets.QTableView)
        self.table.viewport().installEventFilter(self)

    defpaintCell(self, painter, rect, date):
        super().paintCell(painter, rect, date)
        for event in self.list_of_events:
            if event.date == date:
                painter.setBrush(QtCore.Qt.red)
                painter.drawEllipse(rect.topLeft() + QtCore.QPoint(12, 7), 3, 3)

    defeventFilter(self, source, event):
        if (
            event.type() == QtCore.QEvent.MouseButtonDblClick
            and source is self.table.viewport()
        ):
            index = self.table.indexAt(event.pos())
            date = self.dateForCell(index.row(), index.column())
            today_events = [ev for ev in self.list_of_events if ev.date == date]
            if today_events:
                print(today_events)
        returnsuper().eventFilter(source, event)

    defreferenceDate(self):
        refDay = 1while refDay <= 31:
            refDate = QtCore.QDate(self.yearShown(), self.monthShown(), refDay)
            if refDate.isValid():
                return refDate
            refDay += 1return QtCore.QDate()

    @propertydeffirstColumn(self):
        return (
            1if self.verticalHeaderFormat() == QtWidgets.QCalendarWidget.ISOWeekNumbers
            else0
        )

    @propertydeffirstRow(self):
        return (
            0if self.horizontalHeaderFormat()
            == QtWidgets.QCalendarWidget.NoHorizontalHeader
            else1
        )

    defcolumnForDayOfWeek(self, day):
        if day < 1or day > 7:
            return -1
        column = day - self.firstDayOfWeek()
        if column < 0:
            column += 7return column + self.firstColumn

    defcolumnForFirstOfMonth(self, date):
        return (self.columnForDayOfWeek(date.dayOfWeek()) - (date.day() % 7) + 8) % 7defdateForCell(self, row, column):
        if (
            row < self.firstRow
            or row > (self.firstRow + 6 - 1)
            or column < self.firstColumn
            or column > (self.firstColumn + 7 - 1)
        ):
            return QtCore.QDate()
        refDate = self.referenceDate()
        ifnot refDate.isValid():
            return QtCore.QDate()
        columnForFirstOfShownMonth = self.columnForFirstOfMonth(refDate)
        if columnForFirstOfShownMonth - self.firstColumn < 1:
            row -= 1
        requestedDay = (
            7 * (row - self.firstRow)
            + column
            - columnForFirstOfShownMonth
            - refDate.day()
            + 1
        )
        return refDate.addDays(requestedDay)


if __name__ == "__main__":
    import sys

    app = QtWidgets.QApplication(sys.argv)

    events = [
        Todo(QtCore.QDate.currentDate().addDays(random.randint(1, 10)), f"name-{i}")
        for i inrange(15)
    ]

    w = TodoCalendar(events)
    w.show()
    sys.exit(app.exec_())

Post a Comment for "Adding Items To A Qtableview Within Qcalendarwidget"