中文拼音标注工具(pypinyin)

基本功能:

实时拼音标注

- 即时响应:输入中文时自动实时生成拼音

- 多行支持:支持长文本输入,自动显示滚动条

- 智能处理:自动过滤非汉字字符的拼音显示

- ✅ 支持字符类型:
  - 简体中文
  - 繁体中文
  - 中文标点(自动过滤)
  - 数字/字母(保留显示,无拼音)
- ❌ 排除字符:
  - 空格/制表符
  - 常见标点:,。!?、()【】「」《》
  - 特殊符号:@#¥%……&*

导出图片功能:

  • 自动包含拼音和汉字的排版效果- 保存当前显示内容为PNG格式
  • 支持滚动区域当前视图的截图

复制拼音功能:

  • 用空格连接有效拼音
  • 直接存入系统剪贴板
import tkinter as tk
from tkinter import ttk, scrolledtext, messagebox
from pypinyin import pinyin, Style

class PinyinAnnotator:
    def __init__(self, root):
        self.root = root
        self.root.title("中文拼音标注工具")
        self.root.geometry("800x600")
        
        # 创建界面组件
        self.create_widgets()
        
        # 配置样式
        self.configure_styles()
    
    def create_widgets(self):
        """创建界面组件"""
        main_frame = ttk.Frame(self.root)
        main_frame.pack(fill=tk.BOTH, expand=True, padx=10, pady=10)
        
        # 输入区域
        input_frame = ttk.LabelFrame(main_frame, text="输入中文")
        input_frame.pack(fill=tk.X, pady=5)
        
        self.input_text = scrolledtext.ScrolledText(
            input_frame, 
            height=8,
            font=('微软雅黑', 14),
            wrap=tk.WORD
        )
        self.input_text.pack(fill=tk.BOTH, expand=True)
        self.input_text.bind('<KeyRelease>', self.update_pinyin)
        
        # 显示区域
        display_frame = ttk.LabelFrame(main_frame, text="带拼音显示")
        display_frame.pack(fill=tk.BOTH, expand=True, pady=5)
        
        self.display_canvas = tk.Canvas(
            display_frame, 
            bg='white'
        )
        scrollbar = ttk.Scrollbar(
            display_frame, 
            orient="vertical", 
            command=self.display_canvas.yview
        )
        self.display_canvas.configure(yscrollcommand=scrollbar.set)
        
        scrollbar.pack(side=tk.RIGHT, fill=tk.Y)
        self.display_canvas.pack(side=tk.LEFT, fill=tk.BOTH, expand=True)
        
        # 状态栏
        self.status_var = tk.StringVar()
        status_bar = ttk.Label(
            main_frame, 
            textvariable=self.status_var,
            relief=tk.SUNKEN
        )
        status_bar.pack(fill=tk.X)
        
        # 在原控制面板代码后添加新按钮
        control_frame = ttk.Frame(main_frame)
        control_frame.pack(fill=tk.X, pady=5)
        
        ttk.Button(control_frame, text="导出图片", command=self.export_image, 
                  style='TButton').pack(side=tk.LEFT, padx=5)
        ttk.Button(control_frame, text="复制拼音", command=self.copy_pinyin,
                  style='TButton').pack(side=tk.LEFT, padx=5)
    
    def configure_styles(self):
        """配置界面样式"""
        style = ttk.Style()
        style.configure('TLabel', font=('微软雅黑', 10))
        style.configure('TButton', font=('微软雅黑', 10))
        style.configure('TLabelFrame', font=('微软雅黑', 11, 'bold'))
        style.configure('StatusBar.TLabel', font=('微软雅黑', 9))
    
    def get_pinyin(self, text):
        """获取带声调的拼音(过滤标点)"""
        try:
            # 添加自定义处理逻辑
            pinyin_list = []
            for char in text:
                if char.strip() and not self.is_punctuation(char):
                    # 处理汉字
                    py = pinyin(char, style=Style.TONE, errors='ignore')[0][0]
                    pinyin_list.append(py)
                else:
                    # 非汉字字符返回空字符串
                    pinyin_list.append('')
            return pinyin_list
        except Exception as e:
            self.status_var.set(f"错误: {str(e)}")
            return []
    
    def is_punctuation(self, char):
        """判断是否为标点符号"""
        # Unicode标点符号范围
        cp = ord(char)
        return (cp >= 0x2000 and cp <= 0x206F) or \
               (cp >= 0x3000 and cp <= 0x303F) or \
               (cp >= 0xFF00 and cp <= 0xFFEF)
    
    def calculate_layout(self, text, pinyins):
        """计算文本布局"""
        char_width = 30  # 每个字符的显示宽度
        line_height = 60  # 每行高度
        x_start = 20     # 起始X坐标
        y_start = 20     # 起始Y坐标
        
        layout = []
        current_x = x_start
        current_y = y_start
        
        for char, py in zip(text, pinyins):
            # 换行处理
            if current_x + char_width > 780:  # 考虑滚动条宽度
                current_x = x_start
                current_y += line_height
            
            layout.append({
                'char': char,
                'pinyin': py,
                'x': current_x,
                'y': current_y
            })
            
            current_x += char_width
        
        return layout, current_y + line_height
    
    def update_pinyin(self, event=None):
        """更新拼音显示"""
        # 获取输入文本
        text = self.input_text.get("1.0", tk.END).strip()
        if not text:
            self.display_canvas.delete("all")
            self.status_var.set("就绪")
            return
        
        # 生成拼音
        pinyins = self.get_pinyin(text)
        
        # 计算布局
        self.display_canvas.delete("all")
        layout, total_height = self.calculate_layout(text, pinyins)
        
        # 绘制拼音和汉字
        for item in layout:
            # 绘制拼音
            self.display_canvas.create_text(
                item['x'] + 15,
                item['y'],
                text=item['pinyin'],
                fill='#666',
                font=('微软雅黑', 10),
                anchor='s'
            )
            
            # 绘制汉字
            self.display_canvas.create_text(
                item['x'] + 15,
                item['y'] + 25,
                text=item['char'],
                fill='#333',
                font=('微软雅黑', 14),
                anchor='n'
            )
        
        # 更新滚动区域
        self.display_canvas.configure(scrollregion=(
            0, 0, 800, total_height + 20))
        
        self.status_var.set(f"已转换 {len(text)} 个字符")

    def export_image(self):
        """导出当前内容为PNG图片"""
        try:
            from PIL import ImageGrab
            # 获取Canvas在屏幕上的坐标
            x = self.root.winfo_rootx() + self.display_canvas.winfo_x()
            y = self.root.winfo_rooty() + self.display_canvas.winfo_y()
            x1 = x + self.display_canvas.winfo_width()
            y1 = y + self.display_canvas.winfo_height()
            
            # 截屏并保存
            ImageGrab.grab(bbox=(x, y, x1, y1)).save("pinyin_output.png")
            self.status_var.set("图片已保存为 pinyin_output.png")
        except Exception as e:
            messagebox.showerror("导出错误", f"无法保存图片: {str(e)}")

    def copy_pinyin(self):
        """复制拼音文本到剪贴板"""
        text = self.input_text.get("1.0", tk.END).strip()
        if not text:
            self.status_var.set("没有内容可复制")
            return
        
        try:
            pinyins = self.get_pinyin(text)
            # 过滤空拼音并拼接
            py_str = ' '.join([py for py in pinyins if py])
            
            self.root.clipboard_clear()
            self.root.clipboard_append(py_str)
            self.status_var.set("拼音已复制到剪贴板")
        except Exception as e:
            messagebox.showerror("复制错误", f"无法复制拼音: {str(e)}")

if __name__ == "__main__":
    root = tk.Tk()
    app = PinyinAnnotator(root)
    root.mainloop() 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

席子哥哥的代码库

你的鼓励是我最大的动力!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值