如何在PySide2中为QCalendarWidget的禁用日期设置颜色
解决QCalendarWidget自定义超期日期样式的问题
纯靠CSS没法实现你要的需求,因为QCalendarWidget的样式选择器没法针对单个日期的具体范围做区分——你当前用的:enabled/:!enabled是针对视图整体的状态,没法精准定位2022-12-22到2023-1-8这段区间的日期。要实现这个效果,得结合自定义QStyledItemDelegate来逐个判断日期并设置样式。
步骤1:自定义委托类
重写委托的paint方法,判断每个日期是否超过设置的最大日期,对目标区间的日期单独设置颜色:
from PySide2.QtWidgets import QStyledItemDelegate, QCalendarWidget, QApplication, QAbstractItemView from PySide2.QtGui import QPainter, QColor from PySide2.QtCore import QDate, Qt class CalendarDelegate(QStyledItemDelegate): def __init__(self, max_date, parent=None): super().__init__(parent) self.max_date = max_date # 自定义超期日期的颜色,比如红色 self.overdue_color = QColor("#ff0000") def paint(self, painter, option, index): date = index.data(Qt.DisplayRole) if isinstance(date, QDate) and date.isValid(): # 判断日期是否在目标区间(超过最大日期) if date > self.max_date: painter.save() # 对齐方式和默认保持一致 painter.setPen(self.overdue_color) painter.drawText(option.rect, option.displayAlignment, str(date.day())) painter.restore() return # 其他日期用默认样式绘制(遵循你设置的CSS) super().paint(painter, option, index)
步骤2:应用委托和样式
在主程序中设置日历的最大日期,绑定自定义委托,并保留你原来的CSS样式(注意修正background_color的语法错误):
if __name__ == "__main__": app = QApplication([]) calendar = QCalendarWidget() # 设置最大日期为2022-12-22 target_max_date = QDate(2022, 12, 22) calendar.setMaximumDate(target_max_date) # 给日历视图绑定自定义委托 calendar_view = calendar.findChild(QAbstractItemView) delegate = CalendarDelegate(target_max_date, calendar_view) calendar_view.setItemDelegate(delegate) # 你的原有CSS样式(修正语法错误) calendar.setStyleSheet(""" #qt_calendar_calendarview { outline: 0px; selection-background-color: #43ace6; alternate-background-color: #2c313c; background-color: rgb(170, 0, 0); } QCalendarWidget QAbstractItemView:!enabled { color: green; } QCalendarWidget QAbstractItemView:enabled { color: white; } """) calendar.show() app.exec_()
说明
- 委托会拦截每个日期的绘制过程,对超过
max_date的日期使用自定义颜色绘制,其他日期依然遵循你设置的CSS样式(正常日期白色,下月不可用日期绿色)。 - 你可以根据需要修改
overdue_color的值,改成你想要的颜色。
内容的提问来源于stack exchange,提问作者leo
相关产品推荐
相关产品推荐

