接上一期,这期主要讲创建输入框组件。
(一)创建输入框类
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的原因是声母韵母没写全,可以自行补充到字典树的对应声母下面。