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"