QCalendarWidget如何设置多选模式?支持Ctrl多选并返回日期列表
QCalendarWidget 实现多选模式(支持Ctrl键多选)
QCalendarWidget 默认仅提供 NoSelection 和 SingleSelection 两种选择模式,没有原生的多选支持,但可以通过自定义子类实现按住Ctrl键多选日期的功能,核心思路是通过事件监听维护选中日期集合,并自定义绘制选中状态。
实现核心步骤
- 自定义子类继承
QCalendarWidget,用QSet<QDate>(Python中用set)存储选中的日期 - 重写
mousePressEvent:根据Ctrl键状态处理选中逻辑——Ctrl+点击切换当前日期的选中状态,无Ctrl则清空原有选中项并选中当前日期 - 重写
paintCell:对选中日期进行特殊绘制,提供直观的视觉反馈 - 添加公共方法返回排序后的选中日期列表
代码示例(PyQt5)
from PyQt5.QtWidgets import QCalendarWidget, QApplication, QStyle from PyQt5.QtGui import QPainter, QColor from PyQt5.QtCore import QDate, Qt import sys class MultiSelectCalendar(QCalendarWidget): def __init__(self, parent=None): super().__init__(parent) self.selected_dates = set() def mousePressEvent(self, event): date = self.dateAt(event.pos()) if not date.isValid(): super().mousePressEvent(event) return modifiers = QApplication.keyboardModifiers() if modifiers == Qt.ControlModifier: # Ctrl按下:切换当前日期的选中状态 if date in self.selected_dates: self.selected_dates.remove(date) else: self.selected_dates.add(date) else: # 无Ctrl:清空原有选中项,仅选中当前日期 self.selected_dates.clear() self.selected_dates.add(date) self.updateCell(date) super().mousePressEvent(event) def paintCell(self, painter, rect, date): super().paintCell(painter, rect, date) # 绘制选中日期的高亮背景 if date in self.selected_dates: painter.save() highlight_color = self.palette().highlight().color() painter.fillRect(rect, highlight_color) # 绘制白色日期文字,保证可读性 text = str(date.day()) painter.setPen(self.palette().highlightedText().color()) painter.drawText(rect, Qt.AlignCenter, text) painter.restore() def get_selected_dates(self): # 返回排序后的选中日期列表 return sorted(self.selected_dates) if __name__ == "__main__": app = QApplication(sys.argv) cal = MultiSelectCalendar() cal.show() # 示例:点击日历后打印选中日期 def print_selected(): dates = [d.toString(Qt.ISODate) for d in cal.get_selected_dates()] print(f"选中日期:{dates}") cal.clicked.connect(print_selected) sys.exit(app.exec_())
关键细节说明
- 用集合存储选中日期,避免重复选中同一日期
- 重绘逻辑使用系统默认高亮配色,也可替换为自定义颜色(如
QColor("#2196F3")) get_selected_dates返回排序后的列表,方便后续业务处理- 完全贴合原生日历的交互逻辑,用户学习成本低
内容的提问来源于stack exchange,提问作者leo
相关产品推荐
相关产品推荐

