Skip to content

Commit 98fd084

Browse files
authored
Add files via upload
0 parents  commit 98fd084

File tree

1 file changed

+262
-0
lines changed

1 file changed

+262
-0
lines changed

c2po.py

Lines changed: 262 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,262 @@
1+
import tkinter as tk
2+
from tkinter import ttk, filedialog, messagebox
3+
import jieba
4+
from pypinyin import pinyin, Style
5+
import os
6+
import re
7+
8+
class ChineseToPinyinConverter:
9+
def __init__(self):
10+
# 只在类Unix系统上启用并行分词
11+
if os.name != 'nt': # 如果不是Windows系统
12+
try:
13+
jieba.enable_parallel(4)
14+
except:
15+
pass # 如果并行模式失败,继续使用单线程
16+
17+
def convert_text(self, text):
18+
"""将文本中的汉字转换为拼音,按词语组合,保留原始标点符号和格式"""
19+
try:
20+
# 使用正则表达式分割文本,保留所有非汉字字符
21+
pattern = re.compile(r'([\u4e00-\u9fff]+)|([^\u4e00-\u9fff]+)')
22+
result = []
23+
24+
for match in pattern.finditer(text):
25+
chinese_part, non_chinese_part = match.groups()
26+
27+
if chinese_part:
28+
# 使用jieba进行分词
29+
words = jieba.cut(chinese_part, cut_all=False)
30+
pinyin_words = []
31+
32+
for word in words:
33+
# 只处理中文字符
34+
if any('\u4e00' <= char <= '\u9fff' for char in word):
35+
# 获取带音标的拼音
36+
pinyin_list = pinyin(word, style=Style.TONE, heteronym=False)
37+
# 将词语的拼音连在一起,不带空格
38+
pinyin_str = ''.join([item[0].lower() for item in pinyin_list])
39+
pinyin_words.append(pinyin_str)
40+
else:
41+
# 非中文字符直接保留
42+
pinyin_words.append(word)
43+
44+
# 在词语之间添加空格
45+
result.append(' '.join(pinyin_words))
46+
elif non_chinese_part:
47+
# 保留所有非汉字字符(包括标点、时间戳等)
48+
result.append(non_chinese_part)
49+
50+
# 合并所有部分
51+
converted_text = ''.join(result)
52+
53+
# 修复:移除每行前后的多余空格
54+
lines = converted_text.split('\n')
55+
cleaned_lines = [line.strip() for line in lines]
56+
return '\n'.join(cleaned_lines)
57+
58+
except Exception as e:
59+
raise Exception(f"转换过程中出错 (error): {str(e)}")
60+
61+
class PinyinConverterApp:
62+
def __init__(self, root):
63+
self.root = root
64+
self.root.title("C2PO: Chinese to Pinyin Offline 线下汉字转拼音工具")
65+
self.root.geometry("580x650")
66+
67+
# 初始化转换器
68+
self.converter = ChineseToPinyinConverter()
69+
70+
self.setup_ui()
71+
72+
def setup_ui(self):
73+
# 主框架
74+
main_frame = ttk.Frame(self.root, padding="10")
75+
main_frame.pack(fill=tk.BOTH, expand=True)
76+
77+
# 输入标签
78+
input_label = ttk.Label(main_frame, text="Input (Chinese): 输入文本(中文):")
79+
input_label.pack(anchor=tk.W, pady=(0, 5))
80+
81+
# 输入文本框和滚动条
82+
input_frame = ttk.Frame(main_frame)
83+
input_frame.pack(fill=tk.BOTH, expand=True, pady=(0, 10))
84+
85+
self.input_text = tk.Text(input_frame, height=10, wrap=tk.WORD)
86+
input_scrollbar = ttk.Scrollbar(input_frame, orient=tk.VERTICAL, command=self.input_text.yview)
87+
self.input_text.configure(yscrollcommand=input_scrollbar.set)
88+
89+
self.input_text.pack(side=tk.LEFT, fill=tk.BOTH, expand=True)
90+
input_scrollbar.pack(side=tk.RIGHT, fill=tk.Y)
91+
92+
# 按钮框架
93+
button_frame = ttk.Frame(main_frame)
94+
button_frame.pack(fill=tk.X, pady=10)
95+
96+
# 按钮
97+
ttk.Button(button_frame, text="Import 导入文件", command=self.import_file).pack(side=tk.LEFT, padx=(0, 10))
98+
ttk.Button(button_frame, text="Convert 转换为拼音", command=self.convert_text).pack(side=tk.LEFT, padx=(0, 10))
99+
ttk.Button(button_frame, text="Copy 复制结果", command=self.copy_to_clipboard).pack(side=tk.LEFT, padx=(0, 10))
100+
ttk.Button(button_frame, text="Save Output 保存结果", command=self.save_file).pack(side=tk.LEFT, padx=(0, 10))
101+
ttk.Button(button_frame, text="Clear 清空", command=self.clear_text).pack(side=tk.LEFT)
102+
103+
# 输出标签
104+
output_label = ttk.Label(main_frame, text="Output 拼音输出:")
105+
output_label.pack(anchor=tk.W, pady=(10, 5))
106+
107+
# 输出文本框和滚动条
108+
output_frame = ttk.Frame(main_frame)
109+
output_frame.pack(fill=tk.BOTH, expand=True)
110+
111+
self.output_text = tk.Text(output_frame, height=10, wrap=tk.WORD, state=tk.DISABLED)
112+
output_scrollbar = ttk.Scrollbar(output_frame, orient=tk.VERTICAL, command=self.output_text.yview)
113+
self.output_text.configure(yscrollcommand=output_scrollbar.set)
114+
115+
self.output_text.pack(side=tk.LEFT, fill=tk.BOTH, expand=True)
116+
output_scrollbar.pack(side=tk.RIGHT, fill=tk.Y)
117+
118+
# 状态栏
119+
self.status_var = tk.StringVar()
120+
self.status_var.set("Ready 就绪")
121+
status_bar = ttk.Label(main_frame, textvariable=self.status_var, relief=tk.SUNKEN)
122+
status_bar.pack(fill=tk.X, pady=(10, 0))
123+
124+
def import_file(self):
125+
"""Import 导入文件"""
126+
file_path = filedialog.askopenfilename(
127+
title="Choose file 选择文件",
128+
filetypes=[("All files 所有文件", "*.*"), ("TXT file 文本文件", "*.txt"), ("SRT file SRT文件", "*.srt"), ("JSON file JSON文件", "*.json")]
129+
)
130+
131+
if file_path:
132+
try:
133+
# 尝试多种编码
134+
encodings = ['utf-8', 'gbk', 'gb2312', 'utf-16']
135+
content = None
136+
137+
for encoding in encodings:
138+
try:
139+
with open(file_path, 'r', encoding=encoding) as file:
140+
content = file.read()
141+
break
142+
except UnicodeDecodeError:
143+
continue
144+
145+
if content is None:
146+
messagebox.showerror("Error 错误", "Encoding error 无法读取文件,可能是编码问题")
147+
return
148+
149+
self.input_text.delete(1.0, tk.END)
150+
self.input_text.insert(1.0, content)
151+
self.status_var.set(f"Imported 已导入文件: {os.path.basename(file_path)}")
152+
153+
except Exception as e:
154+
messagebox.showerror("Error 错误", f"Error while reading: 读取文件时出错: {str(e)}")
155+
self.status_var.set("Import failed! 导入文件失败")
156+
157+
def convert_text(self):
158+
"""转换文本为拼音"""
159+
input_content = self.input_text.get(1.0, tk.END).strip()
160+
161+
if not input_content:
162+
messagebox.showwarning("Warning 警告", "Nothing to convert 请输入要转换的中文文本")
163+
return
164+
165+
try:
166+
self.status_var.set("Converting 正在转换...")
167+
self.root.update_idletasks() # 强制更新UI
168+
169+
# 转换文本
170+
pinyin_content = self.converter.convert_text(input_content)
171+
172+
# 更新输出文本框
173+
self.output_text.config(state=tk.NORMAL)
174+
self.output_text.delete(1.0, tk.END)
175+
self.output_text.insert(1.0, pinyin_content)
176+
self.output_text.config(state=tk.DISABLED)
177+
178+
self.status_var.set("Conversion complete 转换完成")
179+
180+
except Exception as e:
181+
messagebox.showerror("Error 错误", str(e))
182+
self.status_var.set("Conversion failed 转换失败")
183+
184+
def copy_to_clipboard(self):
185+
"""Copy to clipboard 复制结果到剪贴板"""
186+
output_content = self.output_text.get(1.0, tk.END).strip()
187+
188+
if not output_content:
189+
messagebox.showwarning("Warning 警告", "Nothing to copy 没有内容可复制")
190+
return
191+
192+
try:
193+
# 清空剪贴板并添加新内容
194+
self.root.clipboard_clear()
195+
self.root.clipboard_append(output_content)
196+
# 确保剪贴板内容在程序退出后仍然可用
197+
self.root.update()
198+
199+
self.status_var.set("Copied to clipboard 已复制到剪贴板")
200+
messagebox.showinfo("Success 成功", "Content has been copied to clipboard! 内容已复制到剪贴板!")
201+
202+
except Exception as e:
203+
messagebox.showerror("Error 错误", f"Error while copying to clipboard: 复制到剪贴板时出错: {str(e)}")
204+
self.status_var.set("Copy failed 复制失败")
205+
206+
def save_file(self):
207+
"""Save output to file 保存结果到文件"""
208+
output_content = self.output_text.get(1.0, tk.END).strip()
209+
210+
if not output_content:
211+
messagebox.showwarning("Error 警告", "Nothing to save \n 没有内容可保存")
212+
return
213+
214+
file_path = filedialog.asksaveasfilename(
215+
title="Save file 保存文件",
216+
defaultextension=".txt",
217+
filetypes=[("TXT file 文本文件", "*.txt"), ("All files 所有文件", "*.*")]
218+
)
219+
220+
if file_path:
221+
try:
222+
with open(file_path, 'w', encoding='utf-8') as file:
223+
file.write(output_content)
224+
225+
self.status_var.set(f"File saved as 文件已保存: {os.path.basename(file_path)}")
226+
messagebox.showinfo("Success 成功", "File saved 文件保存成功!")
227+
228+
except Exception as e:
229+
messagebox.showerror("Error 错误", f"Error while saving 保存文件时出错: {str(e)}")
230+
self.status_var.set("Saving failed 保存失败")
231+
232+
def clear_text(self):
233+
"""Clear all text 清空所有文本"""
234+
self.input_text.delete(1.0, tk.END)
235+
self.output_text.config(state=tk.NORMAL)
236+
self.output_text.delete(1.0, tk.END)
237+
self.output_text.config(state=tk.DISABLED)
238+
self.status_var.set("Cleared 已清空")
239+
240+
def main():
241+
# 检查依赖
242+
try:
243+
import jieba
244+
from pypinyin import pinyin, Style
245+
except ImportError as e:
246+
print("Missing package, please install: 缺少必要的依赖库,请安装:")
247+
print("pip install jieba pypinyin")
248+
return
249+
250+
# 创建主窗口
251+
root = tk.Tk()
252+
app = PinyinConverterApp(root)
253+
254+
# 添加测试文本
255+
test_text = """此处可填需要转拼音的汉字内容"""
256+
257+
app.input_text.insert(1.0, test_text)
258+
259+
root.mainloop()
260+
261+
if __name__ == "__main__":
262+
main()

0 commit comments

Comments
 (0)