基于 Tkinter + ttkbootstrap 的桌面密码管理器:从密码生成到凭据管理的完整实现
【免费下载链接】PythonMy Python Examples项目地址: https://gitcode.com/gh_mirrors/py/Python
本篇文章以仓库中 Password Manager Using Tkinter/README.md 为主体,结合其核心实现 main.py 源码,完整讲解一个基于 Python + Tkinter 的本地桌面密码管理器:如何一键生成强密码、以 JSON 文件本地保存网站凭据、按网站快速检索、以及用主密码解锁"查看全部密码"表格。读完本文,你将掌握 Tkinter 桌面应用从 UI 搭建、事件绑定到数据持久化的完整实现路径,并能直接运行、扩展这个项目。
项目定位:把网站登录凭据集中管理在一个地方
这是一个运行在桌面端的个人密码管理器,目标很明确:把散落在各处的网站登录账号(站点名、邮箱/用户名、密码)统一保存到一个本地文件中。应用用 Python 编写,界面走"简洁且美观"路线——既保证功能完整,也照顾使用体验。
从源码 main.py 的整体结构看,它由五段功能模块组成(源码中的注释分区非常清晰):
CONSTANTS:全局常量(字体、主密码);PASSWORD GENERATOR:随机强密码生成;SAVE PASSWORD:凭据写入 JSON;FIND PASSWORD:按网站名快速检索;VIEW ALL PASSWORDS:主密码验证 + 表格展示全部记录。
核心功能一览
README 明确列出的功能清单如下,这些功能在 main.py 中均有对应实现:
| 功能 | 说明 | 对应实现 |
|---|---|---|
| 生成强密码 | 一键生成随机强密码,并自动复制到剪贴板 | generate_password()(main.py) |
| 保存凭据 | 安全保存站点名、邮箱/用户名与密码 | save()(main.py) |
| 快速搜索 | 输入网站名即时查找已保存的登录信息 | find_password()(main.py) |
| 查看全部密码 | 输入主密码解锁,以表格形式查看全部条目 | view_all_passwords()+show_passwords_window()(main.py) |
| 一键复制 | 在表格中选中行,直接复制邮箱或密码 | copy_selected_info()(main.py) |
技术栈与依赖
README 中说明了构建技术,结合仓库文件可以得到完整的依赖清单:
- Python:应用核心逻辑全部由 Python 编写;
- Tkinter:标准库自带,负责桌面 UI 基础框架;
- ttkbootstrap:为原生 Tkinter 控件提供现代化主题皮肤;
- JSON:密码数据以 JSON 格式持久化到本地
data.json文件; - pyperclip:实现"一键复制到剪贴板"能力(源码 main.py 中导入)。
依赖声明非常精简,requirements.txt 中只有一行:
ttkbootstrap需要注意的是,main.py 还导入了pyperclip,因此实际运行时环境中也需要安装该库(pip install pyperclip)。这一点 README 未单独列出,但从源码可以确认它是运行必需项。
快速开始:安装与运行
按照 README 的指引,整个启动流程只需四步:
- 在系统上安装 Python 3;
- 下载项目全部文件(
main.py、logo.png、requirements.txt); - 打开终端/CMD,进入项目目录(即
Password Manager Using Tkinter文件夹),安装依赖:
pip install -r requirements.txt- 启动应用:
python main.py启动后程序会创建主窗口并进入window.mainloop()事件循环(main.py),等待用户交互。
前提与限制:本项目为纯桌面 GUI 应用,需要本地图形环境(如 Windows 桌面、macOS、或安装了 X11 的 Linux);无显示环境(如纯 SSH 服务器)下无法直接运行。
数据存储:data.json 的 JSON 结构与读写策略
应用没有使用数据库,而是把全部凭据保存在与程序同目录的data.json中。仓库自带的 data.json 展示了真实的数据格式——以"网站名"为键、以包含email与password的对象为值:
{ "Amazon": { "email": "prashant123Amazon@gmail.com", "password": "1mD%#Z555rF$&2aRpI" }, "Facebook": { "email": "prashant123Facebook@gmail.com", "password": "qQ6#H7o&)i8S!3sO)c4" }, "Flipkart": { "email": "prashant123Flipkart@gmail.com", "password": "1!+7NqmUZbN18K(3A+" } }写入时采用"先读取整份数据、合并新条目、再整体回写"的方式(main.py),并用indent=4格式化输出,保证文件可读:
try: with open("data.json", "r") as data_file: data = json.load(data_file) except (FileNotFoundError, json.JSONDecodeError): data = {} data.update(new_data) with open("data.json", "w") as data_file: json.dump(data, data_file, indent=4)这里的关键设计点是异常兜底:当data.json不存在或内容损坏(FileNotFoundError/json.JSONDecodeError)时,程序以空字典起步,避免首次运行或文件异常时直接崩溃。三个功能入口(保存、搜索、查看全部)都复用了这套容错模式。
仓库中另有一个名为 data.txt 的空文件以及一份早期草稿 PGV.py,从内容看 PGV.py 记录了更早期的读写思路(只处理了
FileNotFoundError、缺少合并逻辑),与main.py中更健壮的实现形成对照,可视为项目演进过程中的中间版本。
功能实现源码剖析
1. 强密码生成器:字符池 + 随机打乱 + 剪贴板直出
generate_password() 的算法思路非常直观:从三类字符池中按随机数量取样,再整体shuffle打乱顺序,保证密码同时包含大小写字母、数字与符号。
password_letters = [choice(letters) for _ in range(randint(8, 10))] password_symbols = [choice(symbols) for _ in range(randint(2, 4))] password_numbers = [choice(numbers) for _ in range(randint(2, 4))] password_list = password_letters + password_symbols + password_numbers shuffle(password_list)各部分的字符范围与数量规则如下:
| 类别 | 字符池 | 数量(随机) |
|---|---|---|
| 字母 | 26 个小写 + 26 个大写字母 | 8~10 个 |
| 符号 | ! # $ % & ( ) * + | 2~4 个 |
| 数字 | 0-9 | 2~4 个 |
生成的密码总长度约在 12~18 个字符之间。生成后立即写入密码输入框,并通过pyperclip.copy(password)复制到系统剪贴板,同时弹出提示框告知用户"已复制到剪贴板"(main.py)——省去手动复制环节。
2. 保存凭据:非空校验 + 二次确认 + 合并写入
save() 承担"添加记录"职责,流程分三步:
- 字段校验:读取三个输入框的值,若站点名或密码为空,弹出
showerror拒绝保存(main.py); - 二次确认:用
askokcancel弹窗展示即将保存的邮箱与密码,由用户确认后再落盘(main.py),避免误操作覆盖数据; - 合并写入:读取已有 JSON →
data.update(new_data)合并 → 回写文件,随后清空网站与密码输入框便于连续录入(main.py)。
由于使用update()合并,同一网站名重复添加时会覆盖旧记录,而非报错——这是"以网站名为主键"这一数据模型的直接推论。
3. 快速搜索:按网站名精确匹配
find_password() 读取当前输入框中的网站名,在data.json中精确匹配:命中则以showinfo展示该站点的邮箱与密码,并同步把密码复制到剪贴板(连续两次提示"已复制");未命中则给出明确错误提示(main.py)。若数据文件不存在或损坏,同样通过异常兜底给出 "No Data File Found" 提示。
搜索逻辑对应 README 中的Quick Search功能,适合"已知网站名、想快速取回密码"的高频场景。
4. 查看全部密码:主密码解锁 + Treeview 表格 + 一键复制
这是本项目最具"仪式感"的功能,README 也特别提示:"you'll need a password to see your passwords"。
第一步:主密码验证。view_all_passwords() 用simpledialog.askstring(..., show='*')弹出带掩码的输入框,与全局常量MASTER_PASSWORD比对;输入正确才允许打开表格窗口,错误则弹出提示,点击取消(返回None)则静默退出:
password = simpledialog.askstring("Master Password", "Please enter the master password:", show='*') if password == MASTER_PASSWORD: show_passwords_window() elif password is not None: messagebox.showerror("Incorrect Password", "The master password you entered is incorrect.")第二步:表格窗口。show_passwords_window() 创建一个Toplevel子窗口,核心组件是一个三列Treeview(Website/Email/Password),并为每列设定列宽;同时挂载垂直滚动条(ttk.Scrollbar+tree.yview联动),数据量增长后也能完整浏览(main.py)。读取data.json后逐条tree.insert("", "end", values=(website, details['email'], details['password']))填充表格。
第三步:一键复制。表格下方提供 "Copy Email" 与 "Copy Password" 两个按钮(main.py),通过闭包函数copy_selected_info(column_index, info_type)定位当前选中行(tree.focus()),将对应列的值复制到剪贴板;未选中任何行时给出警告。窗口最后调用grab_set()使其成为模态窗口,强制用户先关闭它再回到主界面。
5. UI 布局与主题:ttkbootstrap 的现代化外观
界面部分集中体现在 main.py 的 UI 搭建段:
- 使用
ttk.Window(themename="superhero")创建带主题的主窗口(superhero是 ttkbootstrap 内置深色主题之一); - 用
tk.Canvas绘制应用图标 logo.png(200×200),置于窗口顶部居中; - 三个输入控件按
grid布局排列:Website(带焦点focus())、Email/Username(预填example@email.com占位)、Password; - 按钮按语义使用不同主题样式:搜索用
info.TButton、生成密码用success.TButton、添加用primary.TButton、查看全部用secondary.TButton,形成清晰的视觉层级(main.py)。
整体界面元素与 README 中"简洁且美观"的描述一致,主题化按钮让不同操作一眼可辨。
安全说明(重要)
源码注释与 README 都坦诚地交代了本项目的安全边界,引用时务必注意:
- 主密码是明文硬编码:
MASTER_PASSWORD = "password123"直接写在 main.py 中,且源码注释明确写道:"this is not a secure way to store a master password. in a real application, this should be changed and stored securely (e.g., hashed and salted)"——真实应用中应改为哈希加盐存储; - 密码数据未加密:
data.json以明文 JSON 保存所有密码,任何能读取该文件的人都能直接看到全部凭据; - 适用范围:本项目定位是学习与个人演示,展示 Tkinter 桌面应用、JSON 持久化与基础校验的完整工程组织方式。若要在生产环境使用,应至少做到:将主密码哈希化存储、对
data.json内容加密(如使用cryptography库对称加密)、避免在仓库中提交真实凭据。
文件清单与延伸阅读
项目目录(Password Manager Using Tkinter/)包含以下文件:
- main.py:完整应用入口,全部功能实现;
- README.md:项目说明文档(本文主体);
- requirements.txt:运行依赖(
ttkbootstrap); - data.json:凭据存储文件(含示例数据);
- data.txt:早期预留的数据文件(当前为空);
- PGV.py:早期开发草稿,展示了最初版本的 JSON 读写思路;
- logo.png:应用图标,被主窗口 Canvas 加载显示。
如果你想在此基础上继续深化,可以从源码结构中看到清晰的扩展点:把密码生成规则改为可配置(长度、是否含特殊字符)、为data.json增加加密层、用 SQLite 替代 JSON 存储、将主密码改为哈希验证等——这些改造都不需要推翻现有模块划分,按对应函数替换即可。
【免费下载链接】PythonMy Python Examples项目地址: https://gitcode.com/gh_mirrors/py/Python
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考