如何在PyQt6的QCalendarWidget中为选中日期添加圆角?
问题描述
当前已实现效果:
布局中的日期与日历内容不匹配:
使用PyQt6开发时,需要为QCalendarWidget中用户选中的日期添加45px圆角,现有CalendarWidget.py代码如下:
from __init__ import * class CalendarWidget(QCalendarWidget): def __init__(self, parent=None): super().__init__(parent) self.setGridVisible(False) self.setVerticalHeaderFormat(QCalendarWidget.VerticalHeaderFormat.NoVerticalHeader) self.setHorizontalHeaderFormat(QCalendarWidget.HorizontalHeaderFormat.NoHorizontalHeader) self.setSelectedDate(QDate.currentDate()) self.setNavigationBarVisible(False) for dayOff in (Qt.DayOfWeek.Saturday, Qt.DayOfWeek.Sunday): format = self.weekdayTextFormat(dayOff) format.setForeground(QColor("#CAD3F5")) self.setWeekdayTextFormat(dayOff, format) def paintCell(self, painter, rect, date): if not date.month() == self.selectedDate().month(): painter.save() painter.setPen(QPen(QColor("#939ab7"))) painter.drawText(rect, int(Qt.AlignmentFlag.AlignCenter), str(date.day())) painter.restore() else: QCalendarWidget.paintCell(self, painter, rect, date)
解决方案
要实现选中日期的圆角效果,需要重写paintCell方法,自定义绘制选中日期的背景和文本,具体修改如下:
- 新增选中日期的配色配置,方便调整样式;
- 在
paintCell中判断当前日期是否为选中日期,使用QPainterPath创建45px圆角的矩形路径; - 先绘制圆角背景,再绘制日期文本,避免默认样式覆盖自定义效果。
修改后的完整代码:
from __init__ import * class CalendarWidget(QCalendarWidget): def __init__(self, parent=None): super().__init__(parent) self.setGridVisible(False) self.setVerticalHeaderFormat(QCalendarWidget.VerticalHeaderFormat.NoVerticalHeader) self.setHorizontalHeaderFormat(QCalendarWidget.HorizontalHeaderFormat.NoHorizontalHeader) self.setSelectedDate(QDate.currentDate()) self.setNavigationBarVisible(False) # 周末文本颜色设置 for dayOff in (Qt.DayOfWeek.Saturday, Qt.DayOfWeek.Sunday): format = self.weekdayTextFormat(dayOff) format.setForeground(QColor("#CAD3F5")) self.setWeekdayTextFormat(dayOff, format) # 选中日期的背景色(可按需调整) self.selected_bg_color = QColor("#8AADF4") # 选中日期的文本颜色 self.selected_text_color = QColor("#FFFFFF") def paintCell(self, painter, rect, date): painter.save() # 处理非当前月份的日期 if not date.month() == self.selectedDate().month(): painter.setPen(QPen(QColor("#939ab7"))) painter.drawText(rect, int(Qt.AlignmentFlag.AlignCenter), str(date.day())) else: # 判断是否为选中日期 if date == self.selectedDate(): # 创建圆角矩形路径,圆角半径45px path = QPainterPath() # 若单元格尺寸小于45px,Qt会自动适配圆角半径,避免显示异常 path.addRoundedRect(rect, 45, 45) # 绘制选中背景 painter.fillPath(path, self.selected_bg_color) # 设置选中日期的文本颜色 painter.setPen(self.selected_text_color) painter.drawText(rect, int(Qt.AlignmentFlag.AlignCenter), str(date.day())) else: # 处理周末日期 if date.dayOfWeek() in (Qt.DayOfWeek.Saturday, Qt.DayOfWeek.Sunday): painter.setPen(QPen(QColor("#CAD3F5"))) else: # 普通日期使用默认文本颜色 painter.setPen(self.palette().color(QPalette.Text)) painter.drawText(rect, int(Qt.AlignmentFlag.AlignCenter), str(date.day())) painter.restore()
注意事项
- 重写
paintCell后不再调用父类方法,防止默认选中样式覆盖自定义圆角背景; - 选中日期的配色可通过修改
selected_bg_color和selected_text_color快速调整; - 当单元格宽高小于45px时,Qt会自动缩小圆角半径以适配单元格,保证显示正常。
内容的提问来源于stack exchange,提问作者Vyacheslav Erl
相关产品推荐
相关产品推荐

