Python 日历记事本完整开发教程(自绘日历版)

项目简介

本文将详细讲解如何使用Python的wxPython GUI框架开发一个功能完整的日历记事本应用。该应用支持选择年月、记录每日待办事项、美观预览、背景自定义以及PDF导出等功能。

特别说明:本教程使用自绘日历方式,完全不依赖 wx.calendar 模块,避免了安装问题,更加灵活可控。

技术栈

  • wxPython: 跨平台GUI框架,用于构建用户界面
  • ReportLab: PDF生成库
  • PIL (Pillow): 图像处理库
  • Python标准库: calendar、json、datetime等

一、项目架构设计

1.1 核心类结构

项目包含两个主要类:

CalendarDiary (主窗口类)
├── 数据管理 (JSON读写)
├── UI界面构建
├── 自绘日历实现
├── 事件处理
└── PDF导出功能

PreviewFrame (预览窗口类)
├── 日历图像生成
└── 可视化展示

1.2 数据存储设计

使用JSON格式存储数据,结构如下:

{
  "2025-10-01": {
    "morning": "晨跑 30分钟",
    "noon": "团队会议",
    "evening": "学习Python"
  },
  "2025-10-02": {
    "morning": "",
    "noon": "午餐约会",
    "evening": "看电影"
  }
}

二、主窗口类详解

2.1 初始化方法

def __init__(self):
    super().__init__(None, title="美观日历记事本", size=(1200, 800))
    
    self.data_file = "diary_data.json"
    self.diary_data = self.load_data()
    self.background_image = None
    
    # 初始化日期
    today = datetime.now()
    self.current_year = today.year
    self.current_month = today.month
    self.selected_date = None
    
    self.init_ui()
    self.Centre()

关键点:

  • 调用父类构造函数创建窗口框架
  • 定义数据文件路径
  • 加载历史数据
  • 初始化当前年月和选中日期
  • 构建UI并居中显示

2.2 UI界面构建

2.2.1 布局管理器

wxPython使用Sizer进行布局管理,主要类型:

  • BoxSizer: 水平或垂直排列控件
  • GridSizer: 网格布局
  • FlexGridSizer: 灵活网格布局

本项目使用BoxSizer的嵌套结构:

main_sizer = wx.BoxSizer(wx.VERTICAL)  # 主垂直布局
├── toolbar_sizer (wx.HORIZONTAL)      # 顶部工具栏
├── content_sizer (wx.HORIZONTAL)      # 主内容区
    ├── left_panel (自绘日历)
    └── right_panel (记事区域)
2.2.2 工具栏设计
toolbar_sizer = wx.BoxSizer(wx.HORIZONTAL)

# 年份选择
self.year_choice = wx.Choice(panel, choices=[str(y) for y in range(2020, 2031)])
self.year_choice.SetSelection(self.current_year - 2020)
self.year_choice.Bind(wx.EVT_CHOICE, self.on_year_month_change)

# 月份选择
self.month_choice = wx.Choice(panel, choices=[f"{m}月" for m in range(1, 13)])
self.month_choice.SetSelection(self.current_month - 1)
self.month_choice.Bind(wx.EVT_CHOICE, self.on_year_month_change)

wx.Choice控件特点:

  • 下拉选择框,占用空间小
  • SetSelection() 设置默认选中项(索引从0开始)
  • GetStringSelection() 获取当前选中的文本
  • Bind(wx.EVT_CHOICE, handler) 绑定选择变化事件

三、自绘日历实现(核心技术)

3.1 创建日历面板

# 创建自定义日历
self.calendar_panel = wx.Panel(left_panel, size=(400, 400))
self.calendar_panel.SetBackgroundColour(wx.Colour(255, 255, 255))
self.calendar_panel.Bind(wx.EVT_PAINT, self.on_paint_calendar)
self.calendar_panel.Bind(wx.EVT_LEFT_DOWN, self.on_calendar_click)

关键点:

  • 使用 wx.Panel 作为画布
  • 绑定 wx.EVT_PAINT 事件进行绘制
  • 绑定 wx.EVT_LEFT_DOWN 处理点击事件
  • 设置白色背景色

3.2 绘制日历(核心算法)

def on_paint_calendar(self, event):
    dc = wx.PaintDC(self.calendar_panel)
    dc.Clear()
    
    width, height = self.calendar_panel.GetSize()
    
    # 1. 绘制标题
    dc.SetFont(wx.Font(16, wx.FONTFAMILY_DEFAULT, 
                       wx.FONTSTYLE_NORMAL, wx.FONTWEIGHT_BOLD))
    title = f"{self.current_year}年{self.current_month}月"
    tw, th = dc.GetTextExtent
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值