Python开发英语记忆单词软件 - 优化
修改说明
- 每次启动自动导入:__init__中调用了auto_import_words(),该方法会检查words.md是否存在:
· 存在则导入新单词(去重),并提示新增数量。
· 不存在则创建示例文件,导入示例单词。 - 保留原有数据:导入时仅添加数据库中尚未存在的单词,原有单词的复习记录完全不受影响。
- 兼容新格式:解析规则为## 单词 → 下一行(中文意思)→ 下一非空行(例句,可选)。
- 手动导入功能保持不变,仍可导入其他文件。
现在您每次更新words.md后重启程序,新添加的单词就会自动加入学习队列。
"""
英语单词记忆软件 - 基于记忆曲线的间隔重复学习系统
支持Markdown格式单词本,手动控制释义显示,自动安排复习计划
"""
import sqlite3
import datetime
import re
import os
import random
from tkinter import *
from tkinter import messagebox, filedialog
from tkinter import ttk
class WordMemoryDB:
"""数据库管理类,处理单词存储和记忆曲线算法"""
def __init__(self, db_path='words.db'):
self.db_path = db_path
self.init_database()
def init_database(self):
"""初始化数据库表结构"""
conn = sqlite3.connect(self.db_path)
cursor = conn.cursor()
cursor.execute('''
CREATE TABLE IF NOT EXISTS words (
id INTEGER PRIMARY KEY AUTOINCREMENT,
word TEXT NOT NULL UNIQUE, -- 添加UNIQUE约束防止重复
meaning TEXT,
example TEXT,
repetitions INTEGER DEFAULT 0,
ease_factor REAL DEFAULT 2.5,
interval_days INTEGER DEFAULT 0,
last_review DATE,
next_review DATE
)
''')
conn.commit()
conn.close()
def import_from_markdown(self, md_path):
"""
从Markdown文件导入单词(仅添加新词,不清空原有数据)
新格式:每个单词是一个二级标题(## 单词),后跟中文意思,再跟例句(可选)
返回新增的单词数量
"""
if not os.path.exists(md_path):
raise FileNotFoundError(f"单词本文件不存在: {md_path}")
with open(md_path, 'r', encoding='utf-8') as f:
lines = f.readlines()
# 逐行解析
words_data = []
i = 0
while i < len(lines):
line = lines[i].rstrip('\n')
if line.strip().startswith('## '):
# 提取单词
word = line.strip()[3:].strip()
if not word:
i += 1
continue
# 寻找下一非空行作为中文意思
i += 1
while i < len(lines) and not lines[i].strip():
i += 1
if i >= len(lines):
break # 文件结束,没有意思
meaning = lines[i].strip()
# 寻找下一非空行作为例句(可能没有)
i += 1
while i < len(lines) and not lines[i].strip():
i += 1
if i < len(lines) and not lines[i].strip().startswith('## '):
example = lines[i].strip()
i += 1 # 移动到下一行,准备下一轮
else:
example = "" # 没有例句
# 注意:此时i指向的是下一个单词标题或文件末尾,循环会继续
words_data.append((word, meaning, example))
else:
i += 1
# 获取数据库中已存在的单词(用于去重)
conn = sqlite3.connect(self.db_path)
cursor = conn.cursor()
cursor.execute("SELECT word FROM words")
existing_words = {row[0] for row in cursor.fetchall()}
# 插入新单词(去重)
today = datetime.date.today().isoformat()
new_count = 0
for word, meaning, example in words_data:
if word not in existing_words:
try:
cursor.execute('''
INSERT INTO words (word, meaning, example, last_review, next_review)
VALUES (?, ?, ?, ?, ?)
''', (word, meaning, example, today, today))
new_count += 1
existing_words.add(word)
except sqlite3.IntegrityError:
pass
conn.commit()
conn.close()
return new_count
def get_due_words(self, exclude_ids=None):
"""
获取今天需要复习的单词
exclude_ids: 已在本轮复习过的ID集合
"""
if exclude_ids is None:
exclude_ids = set()
today = datetime.date.today().isoformat()
conn = sqlite3.connect(self.db_path)
cursor = conn.cursor()
# 构建排除条件
placeholders = ','.join(['?'] * len(exclude_ids)) if exclude_ids else ''
query = f'''
SELECT id, word, meaning, example, repetitions, ease_factor, interval_days
FROM words
WHERE next_review <= ? AND id NOT IN ({placeholders})
ORDER BY random()
LIMIT 1
'''
params = [today] + list(exclude_ids) if exclude_ids else [today]
cursor.execute(query, params)
result = cursor.fetchone()
conn.close()
return result
def update_word_review(self, word_id, quality):
"""
根据用户反馈更新单词记忆参数(SM-2算法简化版)
quality: 0=忘记/错误, 1=模糊/困难, 2=正确/记得
"""
conn = sqlite3.connect(self.db_path)
cursor = conn.cursor()
# 获取当前单词数据
cursor.execute('''
SELECT repetitions, ease_factor, interval_days
FROM words WHERE id = ?
''', (word_id,))
row = cursor.fetchone()
if not row:
conn.close()
return
repetitions, ease_factor, interval_days = row
today = datetime.date.today()
if quality >= 2: # 正确
if repetitions == 0:
interval_days = 1
elif repetitions == 1:
interval_days = 3
elif repetitions == 2:
interval_days = 7
elif repetitions == 3:
interval_days = 14
elif repetitions == 4:
interval_days = 30
else:
interval_days = min(interval_days * 1.5, 365) # 最长一年
repetitions += 1
# ease_factor 可适当增加,简化版暂不调整
else: # 忘记或模糊
repetitions = 0
interval_days = 1 if quality == 1 else 0 # 模糊1天,忘记当天复习
# ease_factor 降低,简化版暂不调整
# 计算下次复习日期
next_review = today + datetime.timedelta(days=interval_days)
cursor.execute('''
UPDATE words
SET repetitions = ?, ease_factor = ?, interval_days = ?,
last_review = ?, next_review = ?
WHERE id = ?
''', (repetitions, ease_factor, interval_days,
today.isoformat(), next_review.isoformat(), word_id))
conn.commit()
conn.close()
def get_today_count(self, exclude_ids=None):
"""获取今天待复习单词总数"""
if exclude_ids is None:
exclude_ids = set()
today = datetime.date.today().isoformat()
conn = sqlite3.connect(self.db_path)
cursor = conn.cursor()
placeholders = ','.join(['?'] * len(exclude_ids)) if exclude_ids else ''
query = f'''
SELECT COUNT(*) FROM words
WHERE next_review <= ? AND id NOT IN ({placeholders})
'''
params = [today] + list(exclude_ids) if exclude_ids else [today]
cursor.execute(query, params)
count = cursor.fetchone()[0]
conn.close()
return count
class WordMemoryApp:
"""主应用程序类"""
def __init__(self, root):
self.root = root
self.root.title("英语单词记忆助手 - 记忆曲线版")
self.root.geometry("650x500")
self.root.resizable(False, False)
# 设置样式
self.style = ttk.Style()
self.style.configure('TLabel', font=('微软雅黑', 11))
self.style.configure('Word.TLabel', font=('微软雅黑', 28, 'bold'))
# 数据库实例
self.db = WordMemoryDB()
# 当前复习状态
self.current_word_id = None
self.current_word_data = None
self.reviewed_ids = set() # 本轮已复习的ID
# 默认单词本路径
self.md_path = "words.md"
# 每次启动自动导入默认单词本中的新词
self.auto_import_words()
# 创建界面
self.create_widgets()
# 加载第一个单词
self.load_next_word()
def auto_import_words(self):
"""每次启动时自动从默认的words.md导入新单词"""
if os.path.exists(self.md_path):
try:
new_count = self.db.import_from_markdown(self.md_path)
if new_count > 0:
messagebox.showinfo("导入成功", f"已自动导入 {new_count} 个新单词")
except Exception as e:
messagebox.showerror("错误", f"自动导入失败:{str(e)}")
else:
# 文件不存在,创建示例文件并提示
example_content = """## apple
苹果
This is a red apple.
## book
书
I am reading a book.
## computer
电脑
My computer is fast.
## python
蟒蛇 / Python编程语言
Python is a popular programming language.
"""
with open(self.md_path, 'w', encoding='utf-8') as f:
f.write(example_content)
messagebox.showinfo("提示", f"未找到单词本,已创建示例文件:{self.md_path}")
# 导入示例单词(但数据库可能已有其他单词,只添加新词)
try:
new_count = self.db.import_from_markdown(self.md_path)
if new_count > 0:
messagebox.showinfo("导入成功", f"已自动导入 {new_count} 个示例单词")
except Exception as e:
messagebox.showerror("错误", f"自动导入失败:{str(e)}")
def create_widgets(self):
"""创建界面组件"""
# 顶部信息栏
top_frame = ttk.Frame(self.root, padding=10)
top_frame.pack(fill=X)
self.count_label = ttk.Label(top_frame, text="今日剩余: 计算中...")
self.count_label.pack(side=LEFT)
import_btn = ttk.Button(top_frame, text="重新导入单词本", command=self.import_markdown)
import_btn.pack(side=RIGHT)
# 中间单词显示区
mid_frame = ttk.Frame(self.root, padding=20)
mid_frame.pack(expand=True, fill=BOTH)
self.word_label = ttk.Label(mid_frame, text="", style='Word.TLabel')
self.word_label.pack(pady=20)
self.meaning_frame = ttk.Frame(mid_frame)
self.meaning_frame.pack(fill=BOTH, expand=True, pady=10)
self.meaning_label = ttk.Label(self.meaning_frame, text="",
font=('微软雅黑', 12),
wraplength=550, justify=LEFT)
self.meaning_label.pack()
self.example_label = ttk.Label(self.meaning_frame, text="",
font=('微软雅黑', 11, 'italic'),
foreground='gray',
wraplength=550, justify=LEFT)
self.example_label.pack(pady=5)
# 底部按钮区
bottom_frame = ttk.Frame(self.root, padding=10)
bottom_frame.pack(fill=X)
self.show_btn = ttk.Button(bottom_frame, text="显示释义",
command=self.show_meaning, width=15)
self.show_btn.pack(side=LEFT, padx=5)
# 评分按钮(初始隐藏)
self.rating_frame = ttk.Frame(bottom_frame)
self.rating_frame.pack(side=RIGHT)
self.forget_btn = ttk.Button(self.rating_frame, text="忘记 (0)",
command=lambda: self.rate_word(0),
state=DISABLED, width=8)
self.forget_btn.pack(side=LEFT, padx=2)
self.hard_btn = ttk.Button(self.rating_frame, text="模糊 (1)",
command=lambda: self.rate_word(1),
state=DISABLED, width=8)
self.hard_btn.pack(side=LEFT, padx=2)
self.good_btn = ttk.Button(self.rating_frame, text="记得 (2)",
command=lambda: self.rate_word(2),
state=DISABLED, width=8)
self.good_btn.pack(side=LEFT, padx=2)
def update_count_display(self):
"""更新剩余单词计数"""
count = self.db.get_today_count(self.reviewed_ids)
self.count_label.config(text=f"今日剩余复习: {count} 个单词")
def show_meaning(self):
"""显示释义和例句"""
if self.current_word_data:
_, _, meaning, example, _, _, _ = self.current_word_data
self.meaning_label.config(text=f"【释义】 {meaning}")
self.example_label.config(text=f"📖 {example}" if example else "")
# 切换按钮状态
self.show_btn.config(state=DISABLED)
self.forget_btn.config(state=NORMAL)
self.hard_btn.config(state=NORMAL)
self.good_btn.config(state=NORMAL)
def hide_meaning(self):
"""隐藏释义"""
self.meaning_label.config(text="")
self.example_label.config(text="")
self.show_btn.config(state=NORMAL)
self.forget_btn.config(state=DISABLED)
self.hard_btn.config(state=DISABLED)
self.good_btn.config(state=DISABLED)
def load_next_word(self):
"""加载下一个待复习单词"""
# 隐藏当前释义
self.hide_meaning()
# 获取下一个单词
word_data = self.db.get_due_words(self.reviewed_ids)
if word_data:
self.current_word_id = word_data[0]
self.current_word_data = word_data
word = word_data[1]
self.word_label.config(text=word)
self.reviewed_ids.add(self.current_word_id)
else:
# 没有待复习单词了
self.word_label.config(text="🎉 恭喜!今日复习完成!")
self.current_word_id = None
self.current_word_data = None
self.show_btn.config(state=DISABLED)
self.update_count_display()
def rate_word(self, quality):
"""处理用户评分"""
if self.current_word_id:
# 更新数据库
self.db.update_word_review(self.current_word_id, quality)
# 加载下一个单词
self.load_next_word()
def import_markdown(self):
"""手动导入Markdown文件(仅添加新词)"""
filename = filedialog.askopenfilename(
title="选择单词本文件",
filetypes=[("Markdown files", "*.md"), ("Text files", "*.txt"), ("All files", "*.*")]
)
if filename:
try:
new_count = self.db.import_from_markdown(filename)
# 重置复习状态(新单词立即进入待复习队列)
self.reviewed_ids.clear()
self.load_next_word()
messagebox.showinfo("成功", f"导入完成!新增 {new_count} 个单词")
except Exception as e:
messagebox.showerror("错误", f"导入失败:{str(e)}")
def main():
root = Tk()
app = WordMemoryApp(root)
root.mainloop()
if __name__ == "__main__":
main()
增加删除按钮版本:
"""
英语单词记忆软件 - 基于记忆曲线的间隔重复学习系统
支持Markdown格式单词本,手动控制释义显示,自动安排复习计划
"""
import sqlite3
import datetime
import re
import os
from tkinter import *
from tkinter import messagebox, filedialog
from tkinter import ttk
class WordMemoryDB:
"""数据库管理类,处理单词存储和记忆曲线算法"""
def __init__(self, db_path='words.db'):
self.db_path = db_path
self.init_database()
def init_database(self):
"""初始化数据库表结构"""
conn = sqlite3.connect(self.db_path)
cursor = conn.cursor()
cursor.execute('''
CREATE TABLE IF NOT EXISTS words (
id INTEGER PRIMARY KEY AUTOINCREMENT,
word TEXT NOT NULL UNIQUE,
meaning TEXT,
example TEXT,
repetitions INTEGER DEFAULT 0,
ease_factor REAL DEFAULT 2.5,
interval_days INTEGER DEFAULT 0,
last_review DATE,
next_review DATE
)
''')
conn.commit()
conn.close()
def delete_word(self, word_id):
"""根据ID删除单词"""
conn = sqlite3.connect(self.db_path)
cursor = conn.cursor()
cursor.execute("DELETE FROM words WHERE id = ?", (word_id,))
affected = cursor.rowcount
conn.commit()
conn.close()
return affected > 0
def import_from_markdown(self, md_path):
"""
从Markdown文件导入单词(仅添加新词,不清空原有数据)
新格式:每个单词是一个二级标题(## 单词),后跟中文意思,再跟例句(可选)
返回新增的单词数量
"""
if not os.path.exists(md_path):
raise FileNotFoundError(f"单词本文件不存在: {md_path}")
with open(md_path, 'r', encoding='utf-8') as f:
lines = f.readlines()
# 逐行解析
words_data = []
i = 0
while i < len(lines):
line = lines[i].rstrip('\n')
if line.strip().startswith('## '):
# 提取单词
word = line.strip()[3:].strip()
if not word:
i += 1
continue
# 寻找下一非空行作为中文意思
i += 1
while i < len(lines) and not lines[i].strip():
i += 1
if i >= len(lines):
break
meaning = lines[i].strip()
# 寻找下一非空行作为例句(可能没有)
i += 1
while i < len(lines) and not lines[i].strip():
i += 1
if i < len(lines) and not lines[i].strip().startswith('## '):
example = lines[i].strip()
i += 1
else:
example = ""
words_data.append((word, meaning, example))
else:
i += 1
# 获取数据库中已存在的单词(用于去重)
conn = sqlite3.connect(self.db_path)
cursor = conn.cursor()
cursor.execute("SELECT word FROM words")
existing_words = {row[0] for row in cursor.fetchall()}
# 插入新单词(去重)
today = datetime.date.today().isoformat()
new_count = 0
for word, meaning, example in words_data:
if word not in existing_words:
try:
cursor.execute('''
INSERT INTO words (word, meaning, example, last_review, next_review)
VALUES (?, ?, ?, ?, ?)
''', (word, meaning, example, today, today))
new_count += 1
existing_words.add(word)
except sqlite3.IntegrityError:
pass
conn.commit()
conn.close()
return new_count
def get_due_words(self, exclude_ids=None):
"""获取今天需要复习的单词"""
if exclude_ids is None:
exclude_ids = set()
today = datetime.date.today().isoformat()
conn = sqlite3.connect(self.db_path)
cursor = conn.cursor()
placeholders = ','.join(['?'] * len(exclude_ids)) if exclude_ids else ''
query = f'''
SELECT id, word, meaning, example, repetitions, ease_factor, interval_days
FROM words
WHERE next_review <= ? AND id NOT IN ({placeholders})
ORDER BY random()
LIMIT 1
'''
params = [today] + list(exclude_ids) if exclude_ids else [today]
cursor.execute(query, params)
result = cursor.fetchone()
conn.close()
return result
def update_word_review(self, word_id, quality):
"""根据用户反馈更新单词记忆参数"""
conn = sqlite3.connect(self.db_path)
cursor = conn.cursor()
cursor.execute('''
SELECT repetitions, ease_factor, interval_days
FROM words WHERE id = ?
''', (word_id,))
row = cursor.fetchone()
if not row:
conn.close()
return
repetitions, ease_factor, interval_days = row
today = datetime.date.today()
if quality >= 2: # 正确
if repetitions == 0:
interval_days = 1
elif repetitions == 1:
interval_days = 3
elif repetitions == 2:
interval_days = 7
elif repetitions == 3:
interval_days = 14
elif repetitions == 4:
interval_days = 30
else:
interval_days = min(interval_days * 1.5, 365)
repetitions += 1
else: # 忘记或模糊
repetitions = 0
interval_days = 1 if quality == 1 else 0
next_review = today + datetime.timedelta(days=interval_days)
cursor.execute('''
UPDATE words
SET repetitions = ?, ease_factor = ?, interval_days = ?,
last_review = ?, next_review = ?
WHERE id = ?
''', (repetitions, ease_factor, interval_days,
today.isoformat(), next_review.isoformat(), word_id))
conn.commit()
conn.close()
def get_today_count(self, exclude_ids=None):
"""获取今天待复习单词总数"""
if exclude_ids is None:
exclude_ids = set()
today = datetime.date.today().isoformat()
conn = sqlite3.connect(self.db_path)
cursor = conn.cursor()
placeholders = ','.join(['?'] * len(exclude_ids)) if exclude_ids else ''
query = f'''
SELECT COUNT(*) FROM words
WHERE next_review <= ? AND id NOT IN ({placeholders})
'''
params = [today] + list(exclude_ids) if exclude_ids else [today]
cursor.execute(query, params)
count = cursor.fetchone()[0]
conn.close()
return count
class WordMemoryApp:
"""主应用程序类"""
def __init__(self, root):
self.root = root
self.root.title("英语单词记忆助手 - 记忆曲线版")
self.root.geometry("650x550")
self.root.resizable(False, False)
self.style = ttk.Style()
self.style.configure('TLabel', font=('微软雅黑', 11))
self.style.configure('Word.TLabel', font=('微软雅黑', 28, 'bold'))
self.db = WordMemoryDB()
self.current_word_id = None
self.current_word_data = None
self.reviewed_ids = set()
self.md_path = "words.md"
self.auto_import_words()
self.create_widgets()
self.load_next_word()
def auto_import_words(self):
"""每次启动时自动导入新单词"""
if os.path.exists(self.md_path):
try:
new_count = self.db.import_from_markdown(self.md_path)
if new_count > 0:
messagebox.showinfo("导入成功", f"已自动导入 {new_count} 个新单词")
except Exception as e:
messagebox.showerror("错误", f"自动导入失败:{str(e)}")
else:
example_content = """## apple
苹果
This is a red apple.
## book
书
I am reading a book.
## computer
电脑
My computer is fast.
## python
蟒蛇 / Python编程语言
Python is a popular programming language.
"""
with open(self.md_path, 'w', encoding='utf-8') as f:
f.write(example_content)
messagebox.showinfo("提示", f"未找到单词本,已创建示例文件:{self.md_path}")
try:
new_count = self.db.import_from_markdown(self.md_path)
if new_count > 0:
messagebox.showinfo("导入成功", f"已自动导入 {new_count} 个示例单词")
except Exception as e:
messagebox.showerror("错误", f"自动导入失败:{str(e)}")
def create_widgets(self):
"""创建界面组件"""
top_frame = ttk.Frame(self.root, padding=10)
top_frame.pack(fill=X)
self.count_label = ttk.Label(top_frame, text="今日剩余: 计算中...")
self.count_label.pack(side=LEFT)
import_btn = ttk.Button(top_frame, text="重新导入单词本", command=self.import_markdown)
import_btn.pack(side=RIGHT)
mid_frame = ttk.Frame(self.root, padding=20)
mid_frame.pack(expand=True, fill=BOTH)
self.word_label = ttk.Label(mid_frame, text="", style='Word.TLabel')
self.word_label.pack(pady=20)
self.meaning_frame = ttk.Frame(mid_frame)
self.meaning_frame.pack(fill=BOTH, expand=True, pady=10)
self.meaning_label = ttk.Label(self.meaning_frame, text="",
font=('微软雅黑', 12),
wraplength=550, justify=LEFT)
self.meaning_label.pack()
self.example_label = ttk.Label(self.meaning_frame, text="",
font=('微软雅黑', 11, 'italic'),
foreground='gray',
wraplength=550, justify=LEFT)
self.example_label.pack(pady=5)
bottom_frame = ttk.Frame(self.root, padding=10)
bottom_frame.pack(fill=X)
left_buttons = ttk.Frame(bottom_frame)
left_buttons.pack(side=LEFT)
self.show_btn = ttk.Button(left_buttons, text="显示释义",
command=self.show_meaning, width=12)
self.show_btn.pack(side=LEFT, padx=2)
self.delete_btn = ttk.Button(left_buttons, text="删除单词",
command=self.delete_current_word, width=12)
self.delete_btn.pack(side=LEFT, padx=2)
self.rating_frame = ttk.Frame(bottom_frame)
self.rating_frame.pack(side=RIGHT)
self.forget_btn = ttk.Button(self.rating_frame, text="忘记 (0)",
command=lambda: self.rate_word(0),
state=DISABLED, width=8)
self.forget_btn.pack(side=LEFT, padx=2)
self.hard_btn = ttk.Button(self.rating_frame, text="模糊 (1)",
command=lambda: self.rate_word(1),
state=DISABLED, width=8)
self.hard_btn.pack(side=LEFT, padx=2)
self.good_btn = ttk.Button(self.rating_frame, text="记得 (2)",
command=lambda: self.rate_word(2),
state=DISABLED, width=8)
self.good_btn.pack(side=LEFT, padx=2)
def update_count_display(self):
count = self.db.get_today_count(self.reviewed_ids)
self.count_label.config(text=f"今日剩余复习: {count} 个单词")
def show_meaning(self):
if self.current_word_data:
_, _, meaning, example, _, _, _ = self.current_word_data
self.meaning_label.config(text=f"【释义】 {meaning}")
self.example_label.config(text=f"📖 {example}" if example else "")
self.show_btn.config(state=DISABLED)
self.delete_btn.config(state=DISABLED)
self.forget_btn.config(state=NORMAL)
self.hard_btn.config(state=NORMAL)
self.good_btn.config(state=NORMAL)
def hide_meaning(self):
self.meaning_label.config(text="")
self.example_label.config(text="")
self.show_btn.config(state=NORMAL)
self.delete_btn.config(state=NORMAL)
self.forget_btn.config(state=DISABLED)
self.hard_btn.config(state=DISABLED)
self.good_btn.config(state=DISABLED)
def delete_current_word(self):
"""删除当前单词(需确认)"""
if self.current_word_id is None:
return
word = self.current_word_data[1]
if messagebox.askyesno("确认删除", f"确定要删除单词 \"{word}\" 吗?\n删除后无法恢复。"):
self.db.delete_word(self.current_word_id)
if self.current_word_id in self.reviewed_ids:
self.reviewed_ids.remove(self.current_word_id)
self.load_next_word()
def load_next_word(self):
self.hide_meaning()
word_data = self.db.get_due_words(self.reviewed_ids)
if word_data:
self.current_word_id = word_data[0]
self.current_word_data = word_data
self.word_label.config(text=word_data[1])
self.reviewed_ids.add(self.current_word_id)
else:
self.word_label.config(text="🎉 恭喜!今日复习完成!")
self.current_word_id = None
self.current_word_data = None
self.show_btn.config(state=DISABLED)
self.delete_btn.config(state=DISABLED)
self.update_count_display()
def rate_word(self, quality):
if self.current_word_id:
self.db.update_word_review(self.current_word_id, quality)
self.load_next_word()
def import_markdown(self):
filename = filedialog.askopenfilename(
title="选择单词本文件",
filetypes=[("Markdown files", "*.md"), ("Text files", "*.txt"), ("All files", "*.*")]
)
if filename:
try:
new_count = self.db.import_from_markdown(filename)
self.reviewed_ids.clear()
self.load_next_word()
messagebox.showinfo("成功", f"导入完成!新增 {new_count} 个单词")
except Exception as e:
messagebox.showerror("错误", f"导入失败:{str(e)}")
def main():
root = Tk()
app = WordMemoryApp(root)
root.mainloop()
if __name__ == "__main__":
main()
浙公网安备 33010602011771号