乐于分享
好东西不私藏

PyQt5打造专属单词背诵工具

PyQt5打造专属单词背诵工具

效果图

在碎片化学习成为常态的今天,单词背诵早已是我们提升语言能力的核心环节。但市面上的单词软件要么广告缠身、要么强制捆绑功能、要么词库无法自定义,对于追求高效、私密、个性化学习的我们来说,总觉得差了一口气——有没有一款完全本地运行、无广告打扰、能自己掌控词库、还能遵循科学记忆规律的轻量工具?

今天就带大家从零开始,用Python+PyQt5亲手打造一款专属的桌面单词背诵工具!这款工具完美整合三大核心需求:本地自定义词库(支持TXT文本导入,想背什么单词自己说了算)、随机抽查模式(随时随地检测记忆效果)、艾宾浩斯记忆曲线复习(遵循大脑遗忘规律,让记得更牢、效率翻倍)。

全程基于Python实现,界面简洁美观、操作零门槛,无需联网、无需安装臃肿软件,代码开源可修改,不管是学生党、职场人,还是Python初学者,都能轻松上手,既能用来高效背单词,还能顺便学习PyQt5界面开发、文件操作、算法逻辑等实用编程知识,一举两得!

接下来,我会一步步拆解这款工具的开发逻辑,从界面搭建到核心功能实现,再到完整代码呈现,新手也能跟着直接运行,赶紧收藏学起来!

一、工具核心功能概览

  1. 本地词库管理:读取本地TXT单词文件,自动解析英文+中文释义,无需联网,数据完全私有;
  2. 随机抽查模式:一键随机抽取单词,隐藏/显示释义,自由检测记忆情况;
  3. 艾宾浩斯记忆曲线:自动记录学习时间,按照1、2、4、7、15天的科学周期提醒复习,对抗遗忘;
  4. 简洁GUI界面:PyQt5打造可视化窗口,按钮清晰、操作简单,老少皆宜;
  5. 学习记录保存:本地持久化存储记忆数据,重启工具不丢失。

二、核心代码模块详细解析

这款工具整体分为三大核心模块:PyQt5界面搭建、本地词库加载与随机抽查、艾宾浩斯记忆曲线算法实现,下面逐一拆解讲解。

模块1:PyQt5主界面与窗口初始化

这是工具的视觉框架,我们用PyQt5创建主窗口,设置窗口标题、大小、样式,添加按钮、文本框、标签等控件,实现美观大方的交互界面。 核心知识点:QMainWindow主窗口、QPushButton按钮、QLabel文本标签、QVBoxLayout垂直布局、控件样式美化(背景色、字体、圆角)。 通过布局管理器自动适配窗口,避免控件错乱,同时设置统一的配色方案,让界面简洁不杂乱。

模块2:本地词库加载与随机抽查功能

这是工具的核心功能层,负责读取本地TXT词库文件,解析单词和释义,实现随机抽取单词的逻辑。

  • 词库格式:TXT文件中每行格式为 apple - 苹果,程序自动按分隔符拆分;
  • 随机逻辑:使用Python随机库,从加载的单词列表中随机抽取,避免重复抽查;
  • 交互逻辑:点击「随机抽查」显示单词,点击「显示释义」查看答案,操作极简。 核心知识点:文件读写操作、字符串分割、random随机函数、按钮绑定槽函数。

模块3:艾宾浩斯记忆曲线复习算法

这是工具的科学核心,基于艾宾浩斯遗忘曲线,实现智能复习提醒。

  • 记忆规则:设定5个复习周期(1、2、4、7、15天),完成学习后自动计算下次复习时间;
  • 数据存储:用JSON文件本地保存单词的学习时间、复习次数、状态,持久化不丢失;
  • 复习判断:每次打开工具,自动对比当前时间和复习时间,提醒需要复习的单词。 核心知识点:datetime时间处理、JSON数据持久化、条件判断逻辑。

三、完整可运行代码

直接复制以下代码,安装依赖后即可运行,无需额外配置

第一步:安装依赖

打开命令提示符,执行:

pip install pyqt5

第二步:完整代码

import sys
import random
import json
import datetime
from PyQt5.QtWidgets import (QApplication, QMainWindow, QWidget, QVBoxLayout,
                             QPushButton, QLabel, QMessageBox, QFileDialog)
from PyQt5.QtGui import QFont
from PyQt5.QtCore import Qt

# 艾宾浩斯记忆曲线复习周期(天)
EBBINGHAUS_DAYS = [124715]

classWordReciteTool(QMainWindow):
def__init__(self):
        super().__init__()
        self.setWindowTitle("专属单词背诵工具")
        self.resize(600400)
        self.setStyleSheet("background-color: #f5f5f5;")

# 初始化数据
        self.word_list = []  # 本地词库列表
        self.memory_data = {}  # 记忆数据
        self.current_word = None# 当前抽查单词
        self.load_memory_data()  # 加载记忆数据

# 初始化界面
        self.init_ui()

definit_ui(self):
"""初始化UI界面"""
        central_widget = QWidget()
        self.setCentralWidget(central_widget)
        layout = QVBoxLayout(central_widget)
        layout.setSpacing(20)
        layout.setAlignment(Qt.AlignCenter)

# 标题标签
        title_label = QLabel("单词背诵工具")
        title_label.setFont(QFont("微软雅黑"20, QFont.Bold))
        title_label.setAlignment(Qt.AlignCenter)
        title_label.setStyleSheet("color: #2c3e50; margin: 10px 0;")
        layout.addWidget(title_label)

# 单词显示标签
        self.word_label = QLabel("请先加载本地词库")
        self.word_label.setFont(QFont("微软雅黑"16))
        self.word_label.setAlignment(Qt.AlignCenter)
        self.word_label.setStyleSheet("color: #e74c3c; padding: 20px; border: 1px solid #ddd; background-color: white; border-radius: 8px;")
        layout.addWidget(self.word_label)

# 释义显示标签
        self.trans_label = QLabel("")
        self.trans_label.setFont(QFont("微软雅黑"14))
        self.trans_label.setAlignment(Qt.AlignCenter)
        self.trans_label.setStyleSheet("color: #3498db; padding: 15px; border: 1px solid #ddd; background-color: white; border-radius: 8px;")
        layout.addWidget(self.trans_label)

# 功能按钮
        btn_style = """
        QPushButton{
            font-size:14px;
            padding:10px;
            background-color:#3498db;
            color:white;
            border:none;
            border-radius:6px;
        }
        QPushButton:hover{
            background-color:#2980b9;
        }
        """


        self.load_btn = QPushButton("加载本地词库")
        self.load_btn.clicked.connect(self.load_word_lib)
        self.load_btn.setStyleSheet(btn_style)
        layout.addWidget(self.load_btn)

        self.random_btn = QPushButton("随机抽查单词")
        self.random_btn.clicked.connect(self.random_check_word)
        self.random_btn.setStyleSheet(btn_style)
        layout.addWidget(self.random_btn)

        self.show_trans_btn = QPushButton("显示释义")
        self.show_trans_btn.clicked.connect(self.show_translation)
        self.show_trans_btn.setStyleSheet(btn_style)
        layout.addWidget(self.show_trans_btn)

        self.review_btn = QPushButton("查看待复习单词")
        self.review_btn.clicked.connect(self.check_review_words)
        self.review_btn.setStyleSheet(btn_style)
        layout.addWidget(self.review_btn)

        self.remember_btn = QPushButton("标记已掌握")
        self.remember_btn.clicked.connect(self.mark_remembered)
        self.remember_btn.setStyleSheet(btn_style)
        layout.addWidget(self.remember_btn)

defload_memory_data(self):
"""加载本地记忆数据"""
try:
with open("memory_data.json""r", encoding="utf-8"as f:
                self.memory_data = json.load(f)
except FileNotFoundError:
            self.memory_data = {}

defsave_memory_data(self):
"""保存记忆数据到本地"""
with open("memory_data.json""w", encoding="utf-8"as f:
            json.dump(self.memory_data, f, ensure_ascii=False, indent=4)

defload_word_lib(self):
"""加载本地TXT词库"""
        file_path, _ = QFileDialog.getOpenFileName(self, "选择词库文件""""文本文件(*.txt)")
ifnot file_path:
return
try:
with open(file_path, "r", encoding="utf-8"as f:
                lines = f.readlines()
                self.word_list = []
for line in lines:
                    line = line.strip()
if"-"in line:
                        word, trans = line.split("-"1)
                        self.word_list.append([word.strip(), trans.strip()])
            QMessageBox.information(self, "成功"f"加载完成!共加载{len(self.word_list)}个单词")
            self.word_label.setText("词库加载成功,可开始随机抽查")
except Exception as e:
            QMessageBox.critical(self, "错误"f"词库加载失败:{str(e)}")

defrandom_check_word(self):
"""随机抽查单词"""
ifnot self.word_list:
            QMessageBox.warning(self, "提示""请先加载本地词库!")
return
        self.current_word = random.choice(self.word_list)
        self.word_label.setText(f"单词:{self.current_word[0]}")
        self.trans_label.setText("")

defshow_translation(self):
"""显示释义"""
ifnot self.current_word:
            QMessageBox.warning(self, "提示""请先随机抽查单词!")
return
        self.trans_label.setText(f"释义:{self.current_word[1]}")

defmark_remembered(self):
"""标记单词已掌握,更新记忆曲线"""
ifnot self.current_word:
            QMessageBox.warning(self, "提示""请先抽查单词!")
return
        word = self.current_word[0]
        now = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")

if word notin self.memory_data:
# 首次学习
            self.memory_data[word] = {
"learn_time": now,
"review_count"0,
"next_review": self.calc_next_review(0)
            }
else:
# 复习
            review_count = self.memory_data[word]["review_count"] + 1
if review_count >= len(EBBINGHAUS_DAYS):
                self.memory_data[word]["status"] = "已掌握"
                self.memory_data[word]["next_review"] = "已完成所有复习"
else:
                self.memory_data[word]["review_count"] = review_count
                self.memory_data[word]["next_review"] = self.calc_next_review(review_count)

        self.save_memory_data()
        QMessageBox.information(self, "成功""已标记掌握,系统将自动提醒复习!")

defcalc_next_review(self, review_count):
"""计算下次复习时间"""
        days = EBBINGHAUS_DAYS[review_count]
        next_time = datetime.datetime.now() + datetime.timedelta(days=days)
return next_time.strftime("%Y-%m-%d %H:%M:%S")

defcheck_review_words(self):
"""检查需要复习的单词"""
        now = datetime.datetime.now()
        need_review = []
for word, data in self.memory_data.items():
if data.get("next_review") == "已完成所有复习":
continue
            review_time = datetime.datetime.strptime(data["next_review"], "%Y-%m-%d %H:%M:%S")
if now >= review_time:
                need_review.append(word)

if need_review:
            QMessageBox.information(self, "待复习单词"f"需要复习的单词:\n{', '.join(need_review)}")
else:
            QMessageBox.information(self, "提示""暂无需要复习的单词!")

if __name__ == "__main__":
    app = QApplication(sys.argv)
    window = WordReciteTool()
    window.show()
    sys.exit(app.exec_())

第三步:准备词库文件

新建一个word.txt文件,按照格式填写单词:

apple - 苹果
banana - 香蕉
computer - 电脑
python - 蟒蛇;编程语言
study - 学习

将文件和代码放在同一文件夹,运行代码即可。


四、核心知识点总结

1. PyQt5界面开发知识点

  • 主窗口QMainWindow:作为程序的主容器,承载所有控件;
  • 布局管理器QVBoxLayout:垂直布局,自动排列控件,适配窗口大小;
  • 控件美化:通过Qt样式表(QSS)设置背景色、字体、圆角、悬浮效果,媲美前端界面;
  • 信号与槽:按钮点击事件绑定函数,实现交互逻辑(如点击加载词库触发文件读取)。

2. Python文件操作知识点

  • TXT文件读写:加载本地词库,实现自定义单词数据;
  • JSON文件持久化:存储记忆数据,重启程序不丢失学习记录;
  • 字符编码:统一使用utf-8编码,避免中文乱码。

3. 核心算法与逻辑知识点

  • 随机数算法:random.choice实现随机抽查单词;
  • 艾宾浩斯记忆曲线:基于时间差计算复习周期,科学记忆;
  • 时间处理:datetime模块获取当前时间、计算下次复习时间。

4. 异常处理知识点

  • 文件不存在异常:首次运行无JSON文件时,自动创建空数据;
  • 操作逻辑判断:未加载词库时点击抽查,弹出提示,提升用户体验。

五、拓展场景与测试步骤

一、拓展场景

  1. 学习场景拓展

    • 新增单词发音功能:接入百度/有道翻译API,点击播放单词读音;
    • 新增生词本功能:自动标记未掌握单词,单独复习;
    • 新增学习统计:统计每日学习量、复习完成率,生成学习报告。
  2. 功能场景拓展

    • 支持Excel/CSV词库导入,兼容更多词库格式;
    • 新增单词默写模式,手动输入释义,自动判分;
    • 打包为exe可执行文件:无需安装Python,双击直接运行,分享给同学朋友使用。
  3. 界面场景拓展

    • 新增深色模式,夜间学习更护眼;
    • 自定义界面主题、字体大小,适配不同使用习惯。

二、测试步骤

  1. 基础功能测试

    • 运行代码,打开工具界面,检查窗口、按钮、标签是否正常显示;
    • 点击「加载本地词库」,选择准备好的word.txt,提示加载成功;
    • 点击「随机抽查单词」,正常显示英文单词,释义为空;
    • 点击「显示释义」,正常显示对应中文释义。
  2. 记忆曲线测试

    • 抽查单词后,点击「标记已掌握」,提示保存成功;
    • 打开本地memory_data.json文件,检查是否生成学习记录;
    • 点击「查看待复习单词」,无复习任务时提示正常,模拟过期时间后,正常显示待复习单词。
  3. 异常测试

    • 未加载词库时点击抽查、标记,弹出友好提示;
    • 删除memory_data.json后重启程序,自动重新创建,无报错。

总结

这款PyQt5单词背诵工具,不仅解决了我们个性化背单词的需求,更涵盖了GUI开发、文件操作、算法逻辑、数据持久化四大Python核心技能,非常适合初学者练手。 从界面搭建到核心功能,全程逻辑清晰、代码简洁,你可以根据自己的需求二次开发,打造独一无二的学习工具。赶紧动手试试,用代码提升学习效率,解锁Python实战新技能!

本站文章均为手工撰写未经允许谢绝转载:夜雨聆风 » PyQt5打造专属单词背诵工具

猜你喜欢

  • 暂无文章