淘先锋技术网

首页 1 2 3 4 5 6 7

pygame 实现文本框的程序

提示:这里可以添加系列文章的所有文章的目录,目录需要自己手动添加

提示:写完文章后,目录可以自动生成,如何生成可参考右边的帮助文档


前言

提示:这里可以添加本文要记录的大概内容:

pygame是python的一个图形库,它的很多操作,基本上都是画图操作。对于文本的支持比较少。wxpython对于窗口界面很好实现,但是对于画图的支持又不是那么给力。
今天我们就 自己来用pygame自己做一个文本框。
目标,在窗口里划定一块区域为文本框。有边框,能输入字符。能自动换行,能用“enter”键主动换行。如果字符数较多,文本框会自动扩大。


提示:以下是本篇文章正文内容,下面案例可供参考
程序由两个py文件。第一个,命名为 draw.py。
定义了文本框类 inputBox。
实现 了,对键盘的响应方式。
以及画出 文本框的方式。

import pygame
import os

wenbenkuang_width=200
wenbenkuang_height=100


class InputBox:
    def __init__(self, rect: pygame.Rect = pygame.Rect(100, 100, wenbenkuang_width, wenbenkuang_height)) -> None:
        """
        rect,传入矩形实体,传达输入框的位置和大小
        """
        self.boxBody: pygame.Rect = rect
        self.color_inactive = pygame.Color('lightskyblue3')  # 未被选中的颜色
        self.color_active = pygame.Color('dodgerblue2')  # 被选中的颜色
        self.color = self.color_inactive  # 当前颜色,初始为未激活颜色
        self.active = False
        self.text = ''
        self.done = False
        self.font = pygame.font.Font(None, 32)
        self.cursor=pygame.Rect(self.boxBody.x,self.boxBody.y,1,1)

    def dealEvent(self, event: pygame.event.Event):
        font = pygame.freetype.SysFont('C:/Windows/Fonts/simhei.ttf', 20)
        if(event.type == pygame.MOUSEBUTTONDOWN):
            if(self.boxBody.collidepoint(event.pos)):  # 若按下鼠标且位置在文本框
                self.active = not self.active
            else:
                self.active = False
            self.color = self.color_active if(
                self.active) else self.color_inactive
        if(event.type == pygame.KEYDOWN):  # 键盘输入响应
            if(self.active):
                print(self.text)
                space = font.get_rect(' ')

                line_spacing = font.get_sized_height() + 2
                x, y = 0, line_spacing
                if(event.key == pygame.K_RETURN):
                    print('刚才按键的 unicode', event.unicode)
                    self.text += '\n'
                    #将光标的坐标,置为下一行的开始。
                    self.cursor.x = self.boxBody.x + space.width
                    self.cursor.y = self.cursor.y + line_spacing

                elif(event.key == pygame.K_BACKSPACE):
                    print('刚才按键的 unicode', event.unicode)
                    self.text = self.text[:-1]
                else:
                    print('刚才按键的 unicode', event.unicode)
                    self.text += event.unicode

    def draw(self, screen: pygame.surface.Surface,font):
        font.origin = True
        txtSurface = self.font.render(
            self.text, True, self.color)  # 文字转换为图片
        line_spacing = font.get_sized_height() + 2
        space = font.get_rect(' ')
        self.cursor.x=self.boxBody.x+space.width
        self.cursor.y=self.boxBody.y+line_spacing
        if len(self.text)>0:
            for i in range(0,len(self.text)):
                bounds = font.get_rect(self.text[i])
                if self.text[i]=='\n':
                    self.cursor.x,self.cursor.y=self.boxBody.x+space.width, self.cursor.y+line_spacing
                    if self.cursor.y > self.boxBody.y + self.boxBody.h:
                        self.boxBody.h += line_spacing
                    continue
                if  self.cursor.x+ bounds.width  >= self.boxBody.x+self.boxBody.w:
                    self.cursor.x,self.cursor.y=self.boxBody.x+space.width, self.cursor.y+line_spacing
                if self.cursor.y>self.boxBody.y+self.boxBody.h:
                    self.boxBody.h+=line_spacing
                font.render_to(screen, (self.cursor.x, self.cursor.y), None, (255,0,0))
                self.cursor.x=self.cursor.x+bounds.width+space.width




        pygame.draw.rect(screen, self.color, self.boxBody, 2)  #此处画出了文本框的框边。

第二个文件是 main.py

import pygame
from pygame import Surface
from pygame.constants import QUIT
import pygame.freetype
from draw import InputBox


pygame.init()
WIDTH = 600
HEIGHT = 500
FPS = 120
font = pygame.freetype.SysFont('Arial', 20)
font.origin = True


screen: Surface = None  # 窗口实例
clock = None  # 时钟实例
textFont = None  # 字体


def pygameInit(title: str = "pygame"):
    """初始化 pygame"""
    pygame.init()
    pygame.mixer.init()  # 声音初始化
    pygame.display.set_caption(title)
    global screen, clock, textFont  # 修改全局变量
    screen = pygame.display.set_mode((WIDTH, HEIGHT))
    clock = pygame.time.Clock()

if __name__ == "__main__":
    pygameInit("输入框示例")
    inputbox = InputBox(pygame.Rect(100, 20, 140, 120))  # 输入框
    running = True
    while running:
        clock.tick(FPS)  # 限制帧数
        screen.fill((255, 255, 255))  # 铺底
        for event in pygame.event.get():
            if event.type == QUIT:
                running = False
            inputbox.dealEvent(event)  # 输入框处理事件
        inputbox.draw(screen,font)
        pygame.display.update()
    pygame.quit()

总结

提示:这里对文章进行总结:
pygame中实现了文本框,使我们对于窗口程序中对于文本框的底层机制更加清楚。
但是以上程序还有一个弱点,还没有完全实现中文的输入,下一次我们将呈现中文文本框的 实现。
有问题,欢迎留言或者私信。共同学习和成长。