2020年1月9日 星期四

Pyqt5 calendarWidget 標註特定日期

加入一個calendar時,除了周末之外,平日為黑色字。今天一月一日這世界普遍放假的日子,卻是黑色字標示,而不是紅色字。

除了固定日期的日子,其他像是五月第二個星期天這樣有特定序數的日子,如果能用calendar標記出來那該多好。

標記第三個週三與一月一日

首先,要先決定什麼是「特別」的日子,弄成一份表並將其讀入。
「2020/01/01, 元旦, 假日, 國定假日」
「2020/01/24, 除夕, 假日, 國定假日」如此類的格式



個人是用字典型式,以日期為鍵,其他資料包裝成List為該鍵的內容。

接著回到Pyqt上面,calendar為「QCalendarWidget」,繪製每cell時,呼叫「paintCell」。

為了分離功能與介面,所以定義了新類別「MyCalendarWidget」並繼承QCalendarWidget,之後就在新類別下編寫功能。

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

在定義MyCalendarWidget類別,來修改def paintCell,當碰到特定日期時,用特別的繪製。

    def paintCell(self, painter, rect, date):
        QtWidgets.QCalendarWidget.paintCell(self, painter, rect, date)
        if date.toString("yyyy/MM/dd") in 特定日期字典.keys():
            painter.setPen(QtGui.QColor(255,0,255))
            painter.drawText(QtCore.QRectF(rect), QtCore.Qt.TextSingleLine|QtCore.Qt.AlignCenter, str(date.day()))

特別注意,這裡傳入的date是QDate類型。用toString(“yyyy/MM/dd”),可以得到類似”20200101”的日期字串。用此字串去搜尋特定日期字典,如果有,就看自己想要怎麼標註吧。

這邊我是上了紫色(255,0,255)。

如果想上紅底之類的,可以去尋找Qpainter,然後加入相關程式碼。

【MyCalendarWidget.py】
from PyQt5 import QtWidgets, QtGui, QtCore
class MyCalendarWidget(QtWidgets.QCalendarWidget):
    def __init__(self, parent=None):
        import calendarLoad #讀取特定日期表(dict),需要自定義
        self.calendar = calendarLoad.calendarDict
        super(MyCalendarWidget, self).__init__(parent)

    def paintCell(self, painter, rect, date):
        QtWidgets.QCalendarWidget.paintCell(self, painter, rect, date)
        if date.toString("yyyy/MM/dd") in self.calendar.keys():
            painter.setPen(QtGui.QColor(255,0,255))
            painter.drawText(QtCore.QRectF(rect), QtCore.Qt.TextSingleLine|QtCore.Qt.AlignCenter, str(date.day()))

【calendarLoad.py】
calendarDict = {“2020/01/01”: [“元旦”, “假日”, “國定假日”]}

如果想要第三個周三之類的,個人認為將計算後直接存成資料較好,往後直接取出來用,不用每次都經過計算才能得到資料。