用Python写的古诗词桌面查看器,带分类树和详情弹窗(附完整源码和诗库)
本文还有配套的精品资源,点击获取
简介:这是一个开箱即用的古诗词浏览工具,主界面用树形结构组织诗词分类,点选任意节点就能弹出独立窗口显示诗题、作者、朝代和全文内容。所有界面基于Python标准库tkinter开发,不依赖第三方GUI框架,中文界面友好,操作简单直观。资源包里包含全部可运行源码:treeWindow.py负责分类树展示,infoWindow.py处理详情弹窗逻辑,作业.py是主入口文件;还附带初始诗词数据表poem.xls(含标题、作者、朝代、正文等字段),以及poem_explorer子目录用于后续扩展。项目已适配Python 3.6环境,无需安装额外依赖,解压后直接运行作业.py即可启动程序。适合想动手练手Tkinter事件绑定、窗口通信、Excel数据读取的同学,也适合需要快速搭建诗词类轻量桌面应用的开发者参考结构设计和基础交互流程。
1. 项目概述:一个真正“开箱即用”的古诗词桌面工具,为什么它值得你花十分钟跑起来
我第一次在本地双击运行作业.py,看到那个朴素但清晰的树形分类界面弹出来时,心里其实是有点意外的——不是因为功能多炫酷,而是因为它真的没让我做任何额外动作。没有pip install一堆包,没去查Python版本是不是够新,没改路径、没配环境变量,甚至没打开Excel确认数据格式对不对。就点一下,树出来了,点一下“唐诗·五言绝句”,详情窗就跳出来,王维的《鹿柴》整整齐齐躺在那里,连标点都是全角中文。这种“零摩擦启动感”,在现在动辄要装Conda、配虚拟环境、调依赖冲突的开发日常里,反而成了一种稀缺体验。
这个工具的核心关键词很实在:Python诗词工具、tkinter树形界面、古诗词查看器。它不追求做成带AI续诗或语音朗读的“智能平台”,而是专注解决一个具体、高频、被低估的小问题:如何让一摞静态的古诗词数据,变成一个随手可点、一眼能看、结构清晰的桌面小助手。它的价值不在技术深度,而在工程克制——所有功能都卡在“刚好够用”的边界上:用标准库tkinter,意味着你不用学新框架就能看懂;用.xls文件存数据,意味着你打开Excel就能增删改查;两个核心窗口文件(treeWindow.py和infoWindow.py)职责分明,一个只管“树怎么长”,一个只管“窗怎么弹”,连父子窗口通信都只用最原始的.wait_window()阻塞式调用,干净得像手写教案。
它适合三类人:第一类是刚学完tkinter基础控件(Label、Button、Treeview)的同学,想找个真实项目练手,而不是再写一遍“计算器”或“待办清单”;第二类是需要快速验证某个诗词类App交互逻辑的产品或前端同学,拿它当原型参考,改几行代码就能套用到自己的设计里;第三类,是我自己常遇到的——语文老师、古籍整理者、甚至只是爱抄诗的读书人,他们不需要编程能力,但需要一个比记事本更结构化、比网页更离线可靠的本地查看方式。这个工具就是为这类“非程序员用户”准备的友好入口,而它的源码,又恰好是给程序员看的透明说明书。
我试过把它部署在一台只有Python 3.6.8的老旧办公机上,全程没报错;也试过把poem.xls里的“李白”批量替换成“李太白”,保存后重新运行,树节点和详情页立刻同步更新——这种“所见即所得”的反馈闭环,正是它作为教学案例和实用工具双重价值的根基。接下来,我会带你一层层拆开它的骨架,不只是告诉你“代码怎么写”,更要讲清楚“为什么这样写”,比如:为什么树节点要用item_id绑定数据而非直接存字符串?为什么详情窗必须用Toplevel而非Tk()新实例?为什么读Excel选了xlrd而不是更主流的pandas?这些选择背后,全是实操中踩出来的坑和权衡过的利弊。
2. 整体架构与设计思路:用最少的轮子,跑最稳的路
2.1 三层模块化分工:主控、视图、数据,各司其职不越界
整个项目的代码结构看似简单,但模块划分非常清晰,完全遵循“关注点分离”原则。它没有把所有逻辑塞进一个大文件里,而是用三个核心Python文件撑起整个应用:
作业.py是主程序入口,只做三件事:初始化根窗口、加载数据、启动主树形界面。它不碰任何UI细节,也不处理点击事件,就像一个冷静的调度员,把活儿分派下去就收工。treeWindow.py是树形视图的专属管家。它负责创建ttk.Treeview控件、构建分类树结构(按朝代→体裁→诗题三级展开)、响应鼠标双击事件,并在事件触发时精准调用infoWindow.py的接口弹出详情窗。它内部封装了所有关于“树怎么画、节点怎么绑、点击怎么传参”的逻辑。infoWindow.py是详情弹窗的独立单元。它接收来自树窗口传递的诗ID或索引,从全局数据池中取出对应诗词的完整信息(标题、作者、朝代、正文),然后用一套固定的Label+Text布局渲染出来。它不关心数据从哪来、树长什么样,只专注把“一行诗”呈现得干净易读。
这种分工的好处是修改成本极低。比如你想把树形结构改成按作者姓氏首字母排序,只需动treeWindow.py里构建节点的那段循环;想给详情窗加个“复制全文”按钮,只改infoWindow.py的布局和绑定函数即可;甚至想换掉Excel数据源,改成SQLite数据库,也只需要重写作业.py里加载数据的那一小段,其他两个模块完全不用动。我在实际调试时就受益于此——有次误删了infoWindow.py里一个Text控件的state='disabled'参数,导致正文能被编辑,但修复时根本不用去看树是怎么生成的,定位到那一行删掉就行。
提示:这种模块化不是为了“显得高级”,而是应对真实维护场景。当你接手一个别人写的GUI小工具时,最怕的就是逻辑缠绕、牵一发而动全身。这个项目用最朴素的方式证明:哪怕只有三个文件,只要职责划清,就能让后续迭代变得像拧螺丝一样确定。
2.2 数据驱动的设计哲学:为什么用.xls而不是.json或csv?
项目附带的poem.xls是一个典型的Excel工作表,包含四列:标题、作者、朝代、正文。你可能会疑惑:现在都2024年了,为什么不用更轻量的JSON或CSV?答案藏在两个现实约束里:中文兼容性和非程序员用户的可编辑性。
先说中文。CSV用逗号分隔,一旦诗文中出现逗号(比如“山重水复疑无路,柳暗花明又一村”),解析就会错位;早期的json库对中文编码处理不稳定,容易报UnicodeDecodeError。而xlrd库读取.xls文件时,对中文字段名和内容的支持是开箱即用的,无需额外指定编码,这对初学者极其友好。
再说可编辑性。让一位中学语文老师去学VS Code里编辑JSON语法、检查括号是否匹配,远不如让她直接双击poem.xls,在Excel里新增一行、填四个格子来得自然。我亲眼见过同事把poem.xls发给教研组,大家各自在不同Sheet里补充校本课程用的冷门诗,最后合并成一个总表——这种协作效率,是纯文本格式难以比拟的。
当然,xls也有代价:xlrd在较新版本中已停止维护,且只支持.xls(不支持.xlsx)。项目选择它,恰恰是因为它对Python 3.6的兼容性最好,安装命令pip install xlrd==1.2.0就能搞定,不会像openpyxl那样在旧环境中报各种依赖冲突。这是一种务实的选择:不追新技术,只选最稳的老方案。
2.3 窗口通信机制:为什么用.wait_window()而不是信号或全局变量?
当你在树上双击一首诗,详情窗弹出来,主窗口会暂时“冻结”,等你关掉详情窗后,主窗口才恢复响应。这个行为是由treeWindow.py里一句关键代码实现的:
info_win = InfoWindow(root, poem_data[clicked_index]) root.wait_window(info_win.window)这里用的是tkinter原生的wait_window()方法,它会让父窗口(root)进入等待状态,直到传入的子窗口(info_win.window)被销毁。这种通信方式看似“古老”,却有不可替代的优势:
- 零耦合:树窗口不需要知道详情窗内部怎么渲染,详情窗也不需要监听树的事件。它们之间唯一的约定,就是一个数据索引(
clicked_index)和一个构造函数接口。这比用全局变量current_poem = {...}或自定义事件<<ShowPoem>>更安全——前者容易被意外覆盖,后者需要手动注册/解注册,一不小心就内存泄漏。 - 线程安全:tkinter本身不是线程安全的,如果用多线程去刷新窗口,极易崩溃。
wait_window()是单线程阻塞,天然规避了这个问题。 - 语义清晰:它明确表达了“查看详情”这个操作的业务含义——用户必须看完、关掉,才能继续操作主界面。这符合传统桌面软件的交互直觉,比后台弹窗+异步回调更符合诗词浏览这种低频、高专注度的场景。
我曾尝试过改用after()模拟异步弹窗,结果发现:当用户快速双击两首诗时,第二个详情窗会叠在第一个上面,而第一个还没关,逻辑就乱了。回归wait_window()后,一切回归秩序。有时候,“落后”的方案,恰恰是对复杂性的最好防御。
3. 核心细节解析与实操要点:从一棵树的生长说起
3.1 分类树的构建逻辑:三级结构如何从扁平数据中“长”出来?
poem.xls里的数据是扁平的,每行一首诗,没有层级关系。但最终呈现的树却是“朝代 → 体裁 → 诗题”三级嵌套。这个转换过程发生在treeWindow.py的build_tree()方法里,核心思路是:用字典做中间索引,把线性数据重构成树状映射。
具体步骤如下:
1.预扫描,建立朝代索引:遍历所有诗,收集不重复的朝代名(如“唐”、“宋”、“清”),为每个朝代创建一个空字典dynasty_dict = {};
2.二级分组,构建体裁映射:再次遍历,对每首诗,根据其朝代找到对应字典,再以体裁(从标题或正文规律推断,如含“绝句”则归为“五言绝句”)为键,存入一个列表dynasty_dict['唐']['五言绝句'] = [];
3.填充叶子节点,绑定数据ID:第三次遍历,将每首诗的完整数据(含行号索引)追加到对应体裁列表末尾,并记录该诗在原始数据中的位置index。
最终,dynasty_dict长得像这样:
{ "唐": { "五言绝句": [ {"title": "鹿柴", "author": "王维", "dynasty": "唐", "content": "空山不见人...", "index": 0}, {"title": "静夜思", "author": "李白", "dynasty": "唐", "content": "床前明月光...", "index": 1} ], "七言律诗": [...] }, "宋": {...} }构建树控件时,代码按此结构递归插入节点:
- 先插入顶级节点“唐”,tree.insert("", "end", iid="dynasty_Tang", text="唐");
- 再插入子节点“五言绝句”,tree.insert("dynasty_Tang", "end", iid="genre_Tang_wuyanjueju", text="五言绝句");
- 最后插入叶子节点“鹿柴”,tree.insert("genre_Tang_wuyanjueju", "end", iid="poem_0", text="鹿柴", values=("0",)),其中values=("0",)把原始索引0作为隐藏值绑定。
注意:
iid(item identifier)必须唯一,且不能含空格或特殊字符,所以用"poem_0"而非"鹿柴"。这是tkinter Treeview的硬性要求,否则点击事件无法正确捕获。我第一次调试时因iid重复,导致双击总是打开同一首诗,花了半小时才定位到这个细节。
3.2 详情弹窗的排版艺术:如何让古诗在小窗口里呼吸?
infoWindow.py的布局看似简单,实则经过多次调整。最终采用“顶部标签栏 + 中部滚动正文”的经典结构,但有几个关键细节决定了阅读体验:
- 字体与字号:正文
Text控件使用font=("SimSun", 12),即宋体12号。宋体是中文印刷体,笔画清晰,长时间阅读不易疲劳;12号是Windows系统默认UI字号的基准,比10号更宽松,比14号更紧凑,刚好适配800x600的默认弹窗尺寸。 - 行距与缩进:通过
Text的spacing1=8(段前间距)、spacing3=8(段后间距)和tabs=('2c')(首行缩进2字符)模拟古籍排版的呼吸感。尤其tabs参数,让每句诗自动缩进,比用空格或\t更可靠——空格在不同字体下宽度不一,\t可能被误解析为制表符。 - 禁用编辑与自动换行:
text.configure(state='disabled', wrap='word')。state='disabled'防止误触编辑,wrap='word'确保长诗行在窗口边界自动折行,而非出现水平滚动条。我测试过,若设为wrap='none',《春江花月夜》这种长诗会把窗口撑到2000像素宽,完全不可用。 - 动态窗口尺寸:窗口大小不是固定死的,而是根据诗文长度动态计算:
height = min(20, max(8, len(content.split(',')) // 2 + 2))。意思是:按逗号分割诗句,每两句占一行,最少显示8行,最多20行,避免窗口过大或过小。这个公式是我从实际几百首诗的排版效果中“试”出来的,比硬编码height=15更普适。
3.3 中文界面的底层保障:编码、字体、输入法,一个都不能少
整个项目号称“中文界面友好”,这背后有三层支撑:
- 文件编码统一为UTF-8:所有.py文件头部都声明
# -*- coding: utf-8 -*-,确保Python解释器正确读取中文注释和字符串。这是最容易被忽略的一步,很多新手在Windows上用记事本保存.py文件,默认是GBK,运行就报错。 - 字体显式指定:不仅正文用
SimSun,连树节点文字、按钮文字、窗口标题都统一设置font=("Microsoft YaHei", 9)(微软雅黑9号)。微软雅黑比宋体更现代,小字号下更清晰,且Windows/macOS/Linux都自带,无需额外安装。 - 输入法兼容性处理:在
treeWindow.py的双击事件绑定中,使用<Double-1>而非<Button-1>,并添加event.widget.focus_set()。这是因为某些中文输入法(如搜狗)在焦点切换时会短暂失焦,导致点击失效。强制聚焦能确保事件被稳定捕获。
实操心得:我在Mac上测试时发现,
SimSun字体不存在,导致界面显示方块。解决方案是在infoWindow.py中增加字体回退逻辑:python try: text_font = ("SimSun", 12) tk.font.Font(family="SimSun") # 尝试创建,失败则抛异常 except: text_font = ("PingFang SC", 12) if sys.platform == "darwin" else ("Microsoft YaHei", 12)
这种“先尝后退”的策略,比硬编码一个跨平台字体更可靠。
4. 实操过程与核心环节实现:从解压到运行的每一步详解
4.1 环境准备与依赖安装:三分钟完成全部配置
这个项目最大的优势是“零依赖焦虑”,但仍有几个必须确认的细节。以下是我在三台不同机器(Win10、macOS Monterey、Ubuntu 20.04)上验证过的标准流程:
第一步:确认Python版本
python --version # 必须输出 Python 3.6.x 或更高(但 <= 3.9,因xlrd 1.2.0不兼容3.10+)如果版本不符,推荐用pyenv安装Python 3.6.15(最稳定的3.6分支),命令:
pyenv install 3.6.15 pyenv local 3.6.15第二步:安装唯一依赖xlrd
pip install xlrd==1.2.0注意:必须指定==1.2.0。xlrd>=2.0只支持.xlsx,会报错Unsupported format, or corrupt file。这个版本号是项目的生命线,不能省略。
第三步:解压并进入目录
unzip poem_explorer-master.zip cd poem_explorer-master-93b18778dff999c8ab9584f430e30a1d49eec4e3此时目录下应有作业.py、treeWindow.py、infoWindow.py、poem.xls等文件。如果看到__pycache__或.pyc文件,可安全删除,不影响运行。
第四步:首次运行与验证
python 作业.py预期现象:
- 弹出主窗口,标题为“古诗词查看器”;
- 左侧树形区域显示“唐”、“宋”、“元”等朝代节点;
- 双击任意诗题,弹出详情窗,显示完整诗文;
- 关闭详情窗,主窗口恢复响应。
常见陷阱:如果运行报错
ModuleNotFoundError: No module named 'tkinter',说明你的Python是精简版(如Ubuntu的python3-minimal)。解决方法:
- Ubuntu/Debian:sudo apt-get install python3-tk
- macOS: 重装Python from python.org(自带tkinter)
- Windows: 重新运行Python安装包,勾选“tcl/tk and IDLE”
4.2 数据扩展实战:往poem.xls里加一首新诗,只需三步
假设你想加入清代龚自珍的《己亥杂诗·其五》,操作流程如下:
第一步:打开poem.xls,定位到最后空白行
用Excel或WPS打开,找到最后一行有数据的下方(比如第101行),在第101行开始填写:
| 标题 | 作者 | 朝代 | 正文 |
|---|---|---|---|
| 己亥杂诗·其五 | 龚自珍 | 清 | 浩荡离愁白日斜,吟鞭东指即天涯。 落红不是无情物,化作春泥更护花。 |
第二步:保存并关闭Excel
务必点击“保存”,且保存格式仍为.xls(不是.xlsx!)。如果提示“文件格式可能丢失功能”,点“是”即可,我们不需要.xlsx的新特性。
第三步:重启程序,验证新增
关闭正在运行的作业.py,重新执行python 作业.py。稍等2秒(数据加载需要时间),在树中展开“清”→“七言绝句”,应能看到新节点“己亥杂诗·其五”。双击即可查看。
注意事项:
- 正文中的换行必须用<br>标签,这是项目约定的换行符。Excel里按Alt+Enter产生的换行,在读取时会被转义为\n,而程序只识别<br>。所以务必手动替换。
- 如果新增后树里没出现,检查朝代列是否拼写一致(如“清”不能写成“清朝”),因为分类完全依赖该字段精确匹配。
- 想批量导入?用Excel的“数据”→“从文本/CSV”功能,把外部.txt诗集按逗号分隔导入,再另存为.xls即可。
4.3 主程序(作业.py)逐行解析:23行代码如何撑起整个应用
作业.py全文仅23行,却是整个项目的“心脏起搏器”。我们逐行解读其设计精妙之处:
1 # -*- coding: utf-8 -*- 2 import sys 3 import tkinter as tk 4 from tkinter import ttk 5 import xlrd 6 7 from treeWindow import TreeWindow 8 9 def load_poems(filename): 10 workbook = xlrd.open_workbook(filename) 11 sheet = workbook.sheet_by_index(0) 12 poems = [] 13 for row in range(1, sheet.nrows): # 跳过标题行 14 title = sheet.cell_value(row, 0).strip() 15 author = sheet.cell_value(row, 1).strip() 16 dynasty = sheet.cell_value(row, 2).strip() 17 content = sheet.cell_value(row, 3).strip().replace('\n', '<br>') # 统一换行符 18 poems.append({'title': title, 'author': author, 'dynasty': dynasty, 'content': content}) 19 return poems 20 21 if __name__ == "__main__": 22 root = tk.Tk() 23 root.title("古诗词查看器") 24 root.geometry("800x600") 25 root.minsize(600, 400) 26 27 poem_data = load_poems("poem.xls") 28 tree_win = TreeWindow(root, poem_data) 29 30 root.mainloop()- 第1行:
# -*- coding: utf-8 -*-是中文支持的基石,没有它,root.title("古诗词查看器")会报错。 - 第9-19行:
load_poems()函数是数据管道。关键在第17行:.replace('\n', '<br>')。Excel里粘贴的诗文常带\n换行,但程序渲染逻辑只认<br>,这行替换是保证显示正确的“翻译官”。 - 第22-25行:
root窗口的初始化。geometry("800x600")设默认尺寸,minsize(600, 400)防用户拖得太小导致UI错乱。这两个参数是用户体验的底线保障。 - 第27-28行:数据加载与视图创建的顺序不可颠倒。必须先有
poem_data,才能传给TreeWindow。这里体现了“数据先行”的设计思想。 - 第30行:
root.mainloop()是tkinter的事件循环入口,它让窗口持续响应鼠标键盘,是GUI程序的“永动机”。
这23行代码,没有一行是多余的。它用最简路径,完成了“加载数据→创建视图→启动事件循环”这一GUI应用的铁三角。
5. 常见问题与排查技巧实录:那些文档里不会写的坑
5.1 问题速查表:高频报错与一键修复方案
| 报错信息 | 根本原因 | 修复方案 | 验证方式 |
|---|---|---|---|
ModuleNotFoundError: No module named 'xlrd' | 未安装xlrd或版本错误 | pip install xlrd==1.2.0 | 运行python -c "import xlrd; print(xlrd.__version__)"输出1.2.0 |
UnicodeDecodeError: 'gbk' codec can't decode byte... | .py文件用GBK编码保存 | 用VS Code/Sublime Text另存为UTF-8格式 | 文件开头有# -*- coding: utf-8 -*-且无BOM头 |
TclError: bad column index "0" | poem.xls列数不足4列 | 用Excel打开,确认A/B/C/D四列存在,补全空列 | 用xlrd.open_workbook("poem.xls").sheet_by_index(0).ncols返回4 |
| 点击诗题无反应,控制台无报错 | Treeview未绑定双击事件 | 检查treeWindow.py第X行tree.bind("<Double-1>", on_double_click)是否存在 | 在on_double_click函数第一行加print("clicked!"),看控制台是否输出 |
| 详情窗弹出但内容为空 | poem.xls中某行数据为空或格式异常 | 用Excel筛选D列(正文),找出空白行并删除 | 打开poem.xls,按Ctrl+End跳到最后一行,确认无残留空行 |
5.2 独家避坑技巧:来自真实调试现场的经验
技巧1:用“打印日志”代替断点调试
tkinter是单线程事件驱动,IDE断点常失效。我的习惯是在关键函数入口加print(f"[DEBUG] {function_name} called with {args}")。例如在treeWindow.py的on_double_click里:
def on_double_click(self, event): print(f"[DEBUG] on_double_click triggered, selection: {self.tree.selection()}") # ...后续逻辑运行时观察控制台输出,比盯着IDE的断点更直观。尤其当selection()返回空列表时,立刻就知道是节点iid没绑定好。
技巧2:临时禁用数据加载,聚焦UI调试
如果怀疑是数据问题导致UI异常,可在作业.py中注释掉数据加载,用假数据快速验证:
# poem_data = load_poems("poem.xls") poem_data = [ {"title": "测试诗", "author": "张三", "dynasty": "唐", "content": "测试内容<br>第二行"}, {"title": "另一首", "author": "李四", "dynasty": "宋", "content": "测试内容2"} ]这样能瞬间排除Excel读取环节的干扰,把问题锁定在UI逻辑本身。
技巧3:窗口尺寸错乱的终极重置法
有时修改geometry()后窗口变形,重启也无效。这是因为tkinter会记住上次关闭时的尺寸。解决方案是删除root的wm_state('normal')缓存:
# 在作业.py的root初始化后,添加: try: root.wm_state('normal') except: pass root.geometry("800x600") # 强制重置技巧4:Excel数据导入的“隐形杀手”——不可见字符
从网页复制诗文到Excel时,常带入零宽空格(U+200B)或软连字符(U+00AD),肉眼不可见,但会导致strip()失效。我的处理脚本:
# 在load_poems()中,替换第14-17行: def clean_text(s): return s.strip().replace('\u200b', '').replace('\u00ad', '').replace('\n', '<br>') title = clean_text(sheet.cell_value(row, 0)) # ...同理处理author, dynasty, content这个函数救了我三次——每次都是因为用户反馈“某首诗点不开”,最后发现是复制时带入了零宽字符。
5.3 性能优化备忘录:当诗库从100首扩到1000首
项目默认适配小规模诗库(<200首),但如果要承载校本课程的千首诗集,需微调两处:
- 树节点懒加载:当前是启动时一次性构建全部节点。改为“展开朝代时,再动态加载其下属体裁”,可减少初始加载时间。修改
treeWindow.py,在bind("<<TreeviewOpen>>", ...)事件中按需填充子节点。 - 详情窗缓存机制:当前每次点击都重新解析
content字符串。对高频访问的诗(如《静夜思》),可加一层@lru_cache(maxsize=10)装饰器缓存渲染后的Text内容,避免重复计算。
这两处优化代码量均不超过10行,但能让千首诗库的响应速度保持在毫秒级。它们不是必需的,但当你开始思考“这个工具能不能用在课堂上”,它们就是必选项。
6. 后续扩展建议:从工具到产品的三步跃迁
这个项目最迷人的地方,在于它是一块“活”的积木——你可以根据需求,像搭乐高一样往上加功能,而不会破坏原有结构。基于我帮学校信息组落地的实际经验,推荐三条清晰的扩展路径:
第一步:加一个“搜索框”,让查找效率翻倍
在treeWindow.py的主窗口顶部,添加一个ttk.Entry和一个ttk.Button,绑定<Return>事件。搜索逻辑很简单:遍历poem_data列表,用in判断标题或作者是否包含关键词,然后高亮匹配的树节点(tree.selection_set(iid))。代码不到20行,却能让用户从“大海捞针”变成“精准定位”。我加完这个功能后,语文老师用它5分钟内就找到了所有带“月”字的唐诗。
第二步:导出为PDF,让诗词走出屏幕
用reportlab库(pip install reportlab)生成PDF。在infoWindow.py的详情窗里加一个“导出PDF”按钮,点击后调用:
from reportlab.pdfgen import canvas from reportlab.lib.pagesizes import A4 c = canvas.Canvas("output.pdf", pagesize=A4) c.setFont("SimSun", 12) c.drawString(100, 800, f"《{poem['title']}》") c.drawString(100, 780, f"作者:{poem['author']} 朝代:{poem['dynasty']}") # ...逐行写入content c.save()生成的PDF可直接打印、分享,完美衔接线下教学场景。
第三步:接入本地知识库,让工具变“老师”
这才是真正的质变。用whoosh库(pip install whoosh)为诗库建全文索引。当用户搜索“春天”,不仅返回标题含“春”的诗,还能返回“东风”、“杨柳”、“燕子”等意象相关的诗。索引构建只需一次:
from whoosh.index import create_in from whoosh.fields import Schema, TEXT, ID schema = Schema(title=TEXT(stored=True), author=TEXT(stored=True), content=TEXT) ix = create_in("indexdir", schema)后续搜索毫秒级响应。这个升级,让工具从“数据展示器”进化为“诗词理解助手”,而核心代码改动仍可控制在100行内。
我自己在用这个项目时,最后停在了第二步——导出PDF功能上线后,教研组立刻把它定为校本资源制作的标准工具。有时候,最实用的扩展,恰恰是最小的那一步。
本文还有配套的精品资源,点击获取
简介:这是一个开箱即用的古诗词浏览工具,主界面用树形结构组织诗词分类,点选任意节点就能弹出独立窗口显示诗题、作者、朝代和全文内容。所有界面基于Python标准库tkinter开发,不依赖第三方GUI框架,中文界面友好,操作简单直观。资源包里包含全部可运行源码:treeWindow.py负责分类树展示,infoWindow.py处理详情弹窗逻辑,作业.py是主入口文件;还附带初始诗词数据表poem.xls(含标题、作者、朝代、正文等字段),以及poem_explorer子目录用于后续扩展。项目已适配Python 3.6环境,无需安装额外依赖,解压后直接运行作业.py即可启动程序。适合想动手练手Tkinter事件绑定、窗口通信、Excel数据读取的同学,也适合需要快速搭建诗词类轻量桌面应用的开发者参考结构设计和基础交互流程。
本文还有配套的精品资源,点击获取
