Pygame--解决中文输入问题(二)

文章介绍了使用Pygame库创建一个可交互的输入框组件,包括输入框类的初始化、绘制方法、拼音解析、键盘输入接收以及异常处理。着重展示了如何处理拼音输入并转换为汉字列表。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

接上一期,这期主要讲创建输入框组件。

(一)创建输入框类

import pygame
from Pinyin2Hanzi import DefaultDagParams
from Pinyin2Hanzi import dag

class Input:
    def __init__(self, w, h, x, y, font, DP=DefaultDagParams()):
        self.width = w
        self.height = h
        self.x = x
        self.y = y
        self.cursor_visible = True
        self.text = ""  # 文本框内容
        self.active = False
        self.__surface = pygame.Rect(x, y, w, h)
        self.font = font
        self.dagparams = DP
        self.state = 0 
        self.page = 1
        self.limit = 5 
        self.pinyin = ''
        self.word_list = []
        self.word_list_surf = None 
        self.buffer_text = ''
        self.color_inactive = pygame.Color('lightskyblue3')
        self.color_active = pygame.Color('dodgerblue2')
        self.color = self.color_inactive
        self.cursor_timer = 0
        self.data_buffer = ""
        self.pinyin_tree = pinyin_split.Construction_Dictionary()

DefaultDagParams创建时间比较长建议主类初始化的时候就创建。

(二)draw方法

    def draw(self, dest_surf):
        if self.active:
            color = self.color_active
        else:
            color = self.color_inactive
        text_surf = self.font.render(self.text, True, (0, 0, 0))
        text_rect = text_surf.get_rect()
        text_rect.topleft = (self.__surface.left + 10, self.__surface.centery - text_rect.height // 2)
        pygame.draw.rect(dest_surf, color, self.__surface, 2)
        dest_surf.blit(text_surf, text_rect)
        if self.state == 1:
            dest_surf.blit(self.word_list_surf,
                           (self.x, self.y + (self.height - text_surf.get_height()) - 45),
                           (0, 0, self.width, self.height)
                           )
        if not len(self.text):
            self.reset()
        if self.active:
            pygame.draw.rect(dest_surf, (0, 0, 0), (text_rect.right + 1, text_rect.top + 2, 2, text_rect.height - 2))

(三) 拼音解析

    def py2hz(self, pinyin):
        data = pinyin_split.pinyin_format(self.pinyin_tree,pinyin)
        pinyin_split.Construction_Dictionary()
        result = dag(self.dagparams, data, path_num=self.limit * self.page)[
                 (self.page - 1) * self.limit:self.page * self.limit]
        data = [''.join(item.path) for item in result]
        return data

    def create_word_list_surf(self):
        word_list = [str(index + 1) + '.' + word for index, word in enumerate(self.word_list)]
        text = " ".join(word_list)
        self.word_list_surf = self.font.render(text, True, (0, 0, 0))

(四) 键盘输入接收

 def key_down(self, event):
        unicode = event.unicode
        key = event.key

        if key == 8:
            self.text = self.text[:-1]
            if self.state == 1:
                self.buffer_text = self.buffer_text[:-1]
                self.word_list = self.py2hz(self.buffer_text)
                self.create_word_list_surf()
                self.state = 1
            return

        if key == 301:
            return

        if key == pygame.K_ESCAPE:
            self.text = ""
            self.active = False
            return

        if key == 13:
            print(self.getText())
            return

        if self.state == 1 and key == 32:
            self.state = 0
            self.text = self.text[:-len(self.buffer_text)] + self.word_list[0]
            self.word_list = []
            self.buffer_text = ''
            self.page = 1
            return

        if self.state == 1 and key == 93:
            self.page += 1
            self.word_list = self.py2hz(self.buffer_text)
            if len(self.word_list) == 0:
                self.page -= 1
                self.word_list = self.py2hz(self.buffer_text)
            self.create_word_list_surf()
            return

        if self.state == 1 and key == 91:
            self.page -= 1
            if self.page < 1:
                self.page = 1
            self.word_list = self.py2hz(self.buffer_text)
            self.create_word_list_surf()
            return

        if self.state == 1 and key in (49, 50, 51, 52, 53):
            self.state = 0
            if len(self.word_list) <= key - 49:
                return
            self.text = self.text[:-len(self.buffer_text)] + self.word_list[key - 49]
            self.word_list = []
            self.buffer_text = ''
            self.page = 1
            return

        if unicode != "":
            char = unicode
        else:
            char = chr(key)

        if char in string.ascii_letters:
            self.buffer_text += char
            self.word_list = self.py2hz(self.buffer_text)
            self.create_word_list_surf()
            self.state = 1
        self.text += char


    def safe_key_down(self, event):
        if event.type == MOUSEBUTTONDOWN:
            if self.__surface.collidepoint(event.pos):
                self.active = not self.active
            else:
                self.active = False

        if event.type == KEYDOWN:
            if self.active:
                try:
                    self.key_down(event)
                except:
                    self.reset()

(五)输入异常处理方法

    def reset(self):
        self.state = 0
        self.page = 1
        self.limit = 5
        self.pinyin = ''
        self.word_list = []
        self.word_list_surf = None
        self.buffer_text = ''

(六)获取文本

    def getText(self):
        return self.text

主类应用时创建好input组件并且在对应的区域调用draw绘制后,在对应的event循环内调用safe_key_down方法就可以使用,大部分分词没有问题,有小部分出现bug的原因是声母韵母没写全,可以自行补充到字典树的对应声母下面。

<think>嗯,用户想了解如何在Pygame中监听中文输入。首先,我得回忆一下Pygame的事件处理机制。Pygame通常通过pygame.KEYDOWN事件来获取键盘输入,但这种方法对于英文字符可能没问题,但中文输入可能需要更复杂的处理,比如输入支持。 我记得Pygame有一个事件类型是TEXTINPUT,可能更适合处理文本输入,尤其是Unicode字符。不过,用户可能不知道这一点,或者默认使用KEYDOWN导致无法正确捕获中文。此外,输入法激活的问题,可能需要设置窗口属性来允许输入法启动,比如设置pygame.WINDOW_ALLOW_INPUT_IME之类的标志? 接下来,需要检查是否有必要启用输入支持。在Windows和Linux上,可能需要不同的处理方式。另外,当用户使用输入法时,Pygame是否能够接收到中间输入的字符,比如拼音字母,或者只能在最终确定后才收到中文字符? 可能需要指导用户如何配置Pygame窗口以启用输入法,然后监听TEXTINPUT事件来获取输入的字符。同时,注意在输入过程中,可能会有多个事件触发,比如编辑中的文本,这时候可能需要处理另一个事件类型,比如TEXTEDITING,但这通常用于显示正在输入的组合字符,比如未确定的拼音串。 此外,还需要提醒用户,不同的操作系统可能有不同的行为,需要测试。比如在Linux下,可能需要安装特定的输入法框架,或者配置环境变量。另外,字体支持也很重要,确保中文字符能在Pygame中正确渲染,这可能需要加载中文字体文件,并使用正确的渲染方法。 可能还需要提供一个简单的代码示例,展示如何初始化Pygame,设置窗口属性,处理事件循环,以及如何显示输入中文字符。这样用户可以直接运行代码,观察效果,并根据需要进行调整。 总结一下步骤应该是:1. 设置窗口属性允许输入法;2. 处理TEXTINPUT事件获取中文字符;3. 处理TEXTEDITING事件(如果需要显示输入过程);4. 确保字体支持中文显示。同时,注意不同平台的差异,可能需要用户自行测试和调整。</think>在Pygame中监听中文输入需要特殊处理,以下是分步解决方案: 1. **启用输入支持** ```python import pygame pygame.init() # 设置窗口属性以启用输入pygame.display.set_caption("中文输入") screen = pygame.display.set_mode((800, 600)) screen.fill((255, 255, 255)) font = pygame.font.Font("msyh.ttc", 32) # 必须使用支持中文的字体 ``` 2. **事件处理逻辑** ```python input_text = "" composing = False while True: for event in pygame.event.get(): if event.type == pygame.QUIT: pygame.quit() exit() # 处理文本输入事件 if event.type == pygame.TEXTINPUT: input_text += event.text # 处理文本编辑事件(输入法组合过程) if event.type == pygame.TEXTEDITING: composing = True # 处理退格键 if event.type == pygame.KEYDOWN: if event.key == pygame.K_BACKSPACE: input_text = input_text[:-1] ``` 3. **渲染显示** ```python # 清空屏幕 screen.fill((255, 255, 255)) # 渲染已输入文本 text_surface = font.render(input_text, True, (0, 0, 0)) screen.blit(text_surface, (50, 50)) pygame.display.flip() ``` **关键点说明:** 1. 使用`pygame.TEXTINPUT`事件捕获最终确认的中文字符 2. `pygame.TEXTEDITING`事件用于处理输入法组合过程(如拼音候选) 3. 必须使用支持中文的字体文件(如微软雅黑`msyh.ttc`) **注意事项:** - Windows系统需要设置`PYGAME_HIDE_SUPPORT_PROMPT=1`环境变量 - Linux系统可能需要安装`ibus`或`fcitx`输入法框架 - macOS系统通常自动支持但需要设置正确字体路径 **扩展功能建议:** 1. 添加光标闪烁效果 2. 实现文本框聚焦/失焦逻辑 3. 添加候选词选择功能(需解析输入法事件) 4. 支持多行文本输入 完整示例代码可参考Pygame官方文档中的`ime`模块示例,但需注意中文输入需要额外的字体和输入法配置。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值