You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
216 lines
7.4 KiB
216 lines
7.4 KiB
6 months ago
|
import tkinter as tk
|
||
|
from tkinter import messagebox, filedialog, simpledialog, ttk
|
||
|
|
||
|
import PIL
|
||
|
from PIL import Image, ImageTk
|
||
|
import string
|
||
|
import random
|
||
|
import difflib
|
||
|
import threading
|
||
|
|
||
|
|
||
|
# 从文本文件读取鲁迅名言
|
||
|
def load_quotes(filename):
|
||
|
with open(filename, 'r', encoding='utf-8') as file:
|
||
|
return [line.strip() for line in file if line.strip()]
|
||
|
|
||
|
|
||
|
# 文本预处理函数
|
||
|
def preprocess_text(text):
|
||
|
# 转小写并去除标点符号
|
||
|
return text.lower().translate(str.maketrans('', '', string.punctuation))
|
||
|
|
||
|
|
||
|
def calculate_similarity(input_text, quote):
|
||
|
input_processed = preprocess_text(input_text)
|
||
|
quote_processed = preprocess_text(quote)
|
||
|
return difflib.SequenceMatcher(None, input_processed, quote_processed).ratio()
|
||
|
|
||
|
|
||
|
# 预处理所有名言
|
||
|
def preprocess_all_quotes(quotes):
|
||
|
return [(quote, preprocess_text(quote)) for quote in quotes]
|
||
|
|
||
|
|
||
|
# 搜索名言的函数
|
||
|
def search_quote():
|
||
|
keyword = entry_keyword.get()
|
||
|
if not keyword:
|
||
|
messagebox.showwarning("警告", "请输入搜索关键词!")
|
||
|
return
|
||
|
|
||
|
results = []
|
||
|
progress_bar['value'] = 0
|
||
|
root.update_idletasks()
|
||
|
|
||
|
def search_task():
|
||
|
nonlocal results
|
||
|
keyword_processed = preprocess_text(keyword)
|
||
|
total_quotes = len(preprocessed_quotes)
|
||
|
|
||
|
for i, (quote, processed_quote) in enumerate(preprocessed_quotes):
|
||
|
similarity = difflib.SequenceMatcher(None, keyword_processed, processed_quote).ratio()
|
||
|
if similarity > 0.3 or keyword in quote: # 这里设置一个相似度阈值
|
||
|
highlighted_quote = highlight_keyword(quote, keyword)
|
||
|
results.append(f"相似度: {similarity:.2f}\n原文: {highlighted_quote}")
|
||
|
|
||
|
if (i + 1) % (total_quotes // 100) == 0: # 减少进度条更新频率
|
||
|
progress_bar['value'] = (i + 1) / total_quotes * 100
|
||
|
root.update_idletasks()
|
||
|
|
||
|
progress_bar['value'] = 100
|
||
|
root.update_idletasks()
|
||
|
|
||
|
if results:
|
||
|
show_paginated_results(results)
|
||
|
save_history(keyword, results)
|
||
|
else:
|
||
|
messagebox.showerror("错误", "我是鲁迅,我没有说过这句话!")
|
||
|
|
||
|
threading.Thread(target=search_task).start()
|
||
|
|
||
|
|
||
|
def highlight_keyword(text, keyword):
|
||
|
start = text.lower().find(keyword.lower())
|
||
|
if start != -1:
|
||
|
end = start + len(keyword)
|
||
|
return text[:start] + '[highlight]' + text[start:end] + '[/highlight]' + text[end:]
|
||
|
return text
|
||
|
|
||
|
|
||
|
def show_paginated_results(results):
|
||
|
result_window = tk.Toplevel(root)
|
||
|
result_window.title("查询结果")
|
||
|
|
||
|
result_text = tk.Text(result_window, wrap=tk.WORD, font=('Arial', 12))
|
||
|
result_text.pack(expand=True, fill=tk.BOTH)
|
||
|
|
||
|
for result in results:
|
||
|
result_text.insert(tk.END, result.replace('[highlight]', '').replace('[/highlight]', ''))
|
||
|
result_text.tag_config('highlight', background='yellow', foreground='black')
|
||
|
|
||
|
start_idx = '1.0'
|
||
|
while True:
|
||
|
start_idx = result_text.search('[highlight]', start_idx, stopindex=tk.END)
|
||
|
if not start_idx:
|
||
|
break
|
||
|
end_idx = result_text.search('[/highlight]', start_idx, stopindex=tk.END)
|
||
|
result_text.delete(start_idx, start_idx + '+10c')
|
||
|
result_text.delete(end_idx, end_idx + '+11c')
|
||
|
result_text.tag_add('highlight', start_idx, end_idx)
|
||
|
|
||
|
|
||
|
# 保存历史记录
|
||
|
def save_history(keyword, results):
|
||
|
with open("search_history.txt", "a", encoding='utf-8') as file:
|
||
|
file.write(f"搜索关键词: {keyword}\n")
|
||
|
file.write("\n".join(results) + "\n\n")
|
||
|
|
||
|
|
||
|
# 显示历史记录
|
||
|
def show_history():
|
||
|
history_window = tk.Toplevel(root)
|
||
|
history_window.title("搜索历史记录")
|
||
|
|
||
|
with open("search_history.txt", "r", encoding='utf-8') as file:
|
||
|
history_text = file.read()
|
||
|
|
||
|
history_display = tk.Text(history_window, wrap=tk.WORD, font=('Arial', 12))
|
||
|
history_display.pack(expand=True, fill=tk.BOTH)
|
||
|
history_display.insert(tk.END, history_text)
|
||
|
|
||
|
|
||
|
# 清空历史记录
|
||
|
def clear_history():
|
||
|
if messagebox.askyesno("清空历史记录", "确定要清空所有历史记录吗?"):
|
||
|
with open("search_history.txt", "w", encoding='utf-8') as file:
|
||
|
file.write("")
|
||
|
messagebox.showinfo("提示", "历史记录已清空")
|
||
|
|
||
|
|
||
|
# 导出搜索结果
|
||
|
def export_results():
|
||
|
filename = filedialog.asksaveasfilename(defaultextension=".txt", filetypes=[("Text files", "*.txt")])
|
||
|
if filename:
|
||
|
with open(filename, "w", encoding='utf-8') as file:
|
||
|
keyword = entry_keyword.get()
|
||
|
file.write(f"搜索关键词: {keyword}\n")
|
||
|
for quote, processed_quote in preprocessed_quotes:
|
||
|
similarity = difflib.SequenceMatcher(None, preprocess_text(keyword), processed_quote).ratio()
|
||
|
if similarity > 0.3 or keyword in quote:
|
||
|
file.write(f"相似度: {similarity:.2f}\n原文: {quote}\n")
|
||
|
|
||
|
|
||
|
# 获取随机名言
|
||
|
def get_random_quote():
|
||
|
random_quote = random.choice(quotes)
|
||
|
messagebox.showinfo("随机名言", random_quote)
|
||
|
|
||
|
|
||
|
# 显示关于信息
|
||
|
def show_about():
|
||
|
messagebox.showinfo("关于", "鲁迅名言查询\n版本: 1.0\n作者: Sky")
|
||
|
|
||
|
|
||
|
# 创建主窗口
|
||
|
root = tk.Tk()
|
||
|
root.title("鲁迅名言查询")
|
||
|
|
||
|
# 设置窗口大小
|
||
|
root.geometry("600x500")
|
||
|
|
||
|
# 创建菜单
|
||
|
menu_bar = tk.Menu(root)
|
||
|
root.config(menu=menu_bar)
|
||
|
|
||
|
file_menu = tk.Menu(menu_bar, tearoff=0)
|
||
|
file_menu.add_command(label="导出搜索结果", command=export_results)
|
||
|
file_menu.add_separator()
|
||
|
file_menu.add_command(label="退出", command=root.quit)
|
||
|
menu_bar.add_cascade(label="文件", menu=file_menu)
|
||
|
|
||
|
history_menu = tk.Menu(menu_bar, tearoff=0)
|
||
|
history_menu.add_command(label="查看历史记录", command=show_history)
|
||
|
history_menu.add_command(label="清空历史记录", command=clear_history)
|
||
|
menu_bar.add_cascade(label="历史记录", menu=history_menu)
|
||
|
|
||
|
help_menu = tk.Menu(menu_bar, tearoff=0)
|
||
|
help_menu.add_command(label="关于", command=show_about)
|
||
|
menu_bar.add_cascade(label="帮助", menu=help_menu)
|
||
|
|
||
|
# 加载图片并显示Logo
|
||
|
image_path = "image.png"
|
||
|
image = PIL.Image.open(image_path)
|
||
|
logo_image = PIL.ImageTk.PhotoImage(image)
|
||
|
logo_label = tk.Label(root, image=logo_image)
|
||
|
logo_label.pack(side=tk.LEFT, padx=10, pady=10)
|
||
|
|
||
|
# 从文件加载名言
|
||
|
quotes = load_quotes("book.txt")
|
||
|
preprocessed_quotes = preprocess_all_quotes(quotes) # 预处理所有名言
|
||
|
|
||
|
# 创建输入框和搜索按钮
|
||
|
input_frame = tk.Frame(root)
|
||
|
input_frame.pack(side=tk.RIGHT, padx=20, pady=20)
|
||
|
|
||
|
entry_keyword = tk.Entry(input_frame, font=('Arial', 14), width=30)
|
||
|
entry_keyword.pack(side=tk.TOP, pady=10)
|
||
|
|
||
|
btn_search = tk.Button(input_frame, text="搜索名言", font=('Arial', 14), command=search_quote)
|
||
|
btn_search.pack(side=tk.TOP)
|
||
|
|
||
|
btn_random = tk.Button(input_frame, text="随机名言", font=('Arial', 14), command=get_random_quote)
|
||
|
btn_random.pack(side=tk.TOP)
|
||
|
|
||
|
btn_history = tk.Button(input_frame, text="查看历史记录", font=('Arial', 14), command=show_history)
|
||
|
btn_history.pack(side=tk.TOP)
|
||
|
|
||
|
btn_export = tk.Button(input_frame, text="导出搜索结果", font=('Arial', 14), command=export_results)
|
||
|
btn_export.pack(side=tk.TOP)
|
||
|
|
||
|
progress_bar = ttk.Progressbar(root, orient='horizontal', mode='determinate', length=400)
|
||
|
progress_bar.pack(side=tk.BOTTOM, pady=10)
|
||
|
|
||
|
# 运行主循环
|
||
|
root.mainloop()
|