上一篇文章:
Python pygame(GUI编程)模块最完整教程(1)_pygame模块详解_Python-ZZY的博客-CSDN博客
总目录:
README.md · Python-ZZY/Python-Pygame最完整教程 - Gitee.com
6 文字绘制
参考资料:pygame.font — pygame-ce v2.4.0 documentation
6.1 载入字体
pygame中绘制文字的第一步是载入字体。载入字体的方式通常有两种,第一种是使用指定路径的字体文件,第二种是从系统字体库中载入字体。推荐第一种方式,因为在游戏打包后,你无法确定你电脑上安装的字体文件在其他用户的电脑上也安装过。
pygame.font和pygame.freetype模块提供了文字绘制的操作。font模块功能比较简单,freetype模块是font模块功能的扩展。
Font类通过字体文件创建一个字体对象,支持包括*.ttf等一系列的TrueType字体。载入字体时,需要提供一个字体文件路径和字体大小。示例:
font = pg.font.Font("name_of_font.ttf", 12)
如果是调用系统字体文件,则使用SysFont。示例:
font = pg.font.SysFont("宋体", 12)
6.2 渲染字体
加载字体后,下一步是渲染字体。渲染字体调用字体对象的render()方法,将一段文字转换成使用该字体的pygame.Surface对象。
render(text, antialias, color, bgcolor=None, wraplength=0) -> Surface
text是要渲染的一段文字内容。
注意:pygame-ce 2.1.4版本之前不支持渲染换行符"\n"。
antialias是一个布尔值,代表是否使用抗锯齿,抗锯齿的文字更加平滑,但是速度会稍慢一点点,一般选择True。color是文字的颜色。background是文字背景颜色,设为None则为透明背景。
注意:如果文字绘制的位置始终是纯色背景,那么最好是指定background背景颜色。因为使用纯色填充比使用透明填充性能会更好。
渲染后的字体可以当做表面来处理。下面的示例显示了如何绘制文字。
import pygame as pg
pg.init()
screen = pg.display.set_mode((300, 200))
font = pg.font.Font("simhei.ttf", 20) #大小为20的simhei字体文件(在同一目录下)
surf = font.render("你好!这是一段文字", True, (255, 255, 255))
while True:
screen.fill((0, 0, 0))
screen.blit(surf, (0, 0))
for event in pg.event.get():
if event.type == pg.QUIT:
pg.quit()
pg.display.flip()
注意:字体渲染不是线程安全的。这意味着你无法用多线程渲染单个字体,同一时刻只能用该字体对象渲染一段文字。如果一定要用线程,可以建立多个Font对象,但每个对象都是一样渲染结果。
6.3 字体特殊样式
Font对象提供了几个属性获取或改变字体的特殊样式,包括加粗、斜体、下划线、删除线。
属性 |
解释 |
bold |
加粗 |
italic |
斜体 |
underline |
下划线 |
strikethrough |
删除线 |
例如想要让字体加粗、斜体,可以这样:
font.bold = font.italic = True
下面的示例演示了四种效果。
import pygame as pg
pg.init()
screen = pg.display.set_mode((300, 200))
surfs = []
font = pg.font.SysFont("simhei", 20)
surfs.append(font.render("default style", True, (255, 255, 255)))
for style in ("bold", "italic", "underline", "strikethrough"):
font = pg.font.SysFont("simhei", 20)
setattr(font, style, True)
surfs.append(font.render(style, True, (255, 255, 255)))
while True:
screen.fill((0, 0, 0))
for i, surf in enumerate(surfs):
screen.blit(surf, (0, i * 40))
for event in pg.event.get():
if event.type == pg.QUIT:
pg.quit()
pg.display.flip()
6.4 文本自动换行
注意:pygame-ce 2.3.0版本可用
render方法包含关键字参数wraplength,它指定一个像素长度,当字体长度超过wraplength将自动换行(并且确保换行前后字母是一个完整的单词)。
font = pg.font.SysFont("simhei", 20)
surf = font.render("This is a long long long long string.", True, (255, 255, 255), bgcolor=(255, 0, 0), wraplength=120)
这样,字体长度达到120像素后会自动换行。
font还有一个可设定的属性align,指定字体换行时统一靠向哪个地方。可选常量如下:
-
pg.FONT_LEFT:靠向左侧(默认)
-
pg.FONT_CENTER:靠向中间
-
pg.FONT_RIGHT:靠向右侧
font = pg.font.SysFont("simhei", 20)
font.align = pg.FONT_CENTER
surf = font.render("This is a long long long long string.", True, (255, 255, 255), (255, 0, 0), 120)
6.5 文本绘制方向
注意:pygame-ce 2.1.4版本可用
Font.set_direction方法设置文本的呈现方向,包含一个参数direction,可以设为如下常量值:
-
pg.DIRECTION_LTR:从左到右
-
pg.DIRECTION_RTL:从右到左
-
pg.DIRECTION_TTB:从上到下
-
pg.DIRECTION_BTT:从下到上
注意:从上到下和从下到上渲染时,文本中换行符\n效果不佳
import pygame as pg
pg.init()
screen = pg.display.set_mode((300, 500))
surfs = []
font = pg.font.SysFont("simhei", 20)
for style in (pg.DIRECTION_LTR, pg.DIRECTION_RTL, pg.DIRECTION_TTB,
pg.DIRECTION_BTT):
font.set_direction(style)
surfs.append(font.render("HelloWorld!", True, (255, 255, 255), (255, 0, 0)))
while True:
screen.fill((0, 0, 0))
for i, surf in enumerate(surfs):
screen.blit(surf, (i * 40, i * 40))
for event in pg.event.get():
if event.type == pg.QUIT:
pg.quit()
pg.display.flip()
6.6 font模块索引-字体操作
get_default_font() -> string
获取pygame指定的默认的字体名称,一般是freesansbold.ttf。
get_fonts() -> list of strings
获取系统上所有可用的字体名称。
match_font(name, bold=False, italic=False) -> path
返回系统上名为name的字体的完整路径。
SysFont(name, size, bold=False, italic=False) -> Font
从系统上调用字体,name为字体名,size为字体大小,bold和italic表示是否设为粗体或斜体。
Font(filename, size) -> Font
Font(pathlib.Path, size) -> Font
Font(object, size) -> Font
从文件载入字体。
Font.render(text, antialias, color, bgcolor=None, wraplength=0) -> Surface
通过字体渲染文字,text为文字内容,antialias表示是否抗锯齿,color是文字颜色,background为背景颜色(None为透明),wraplength为换行长度。
Font.size(text) -> (width, height)
返回渲染一段文字所需的表面大小。
Font.set_underline(bool) -> None
Font.get_underline() -> bool
设置和获取文本的下划线状态。
Font.set_strikethrough(bool) -> None
Font.get_strikethrough() -> bool
设置和获取文本的删除线状态。
Font.set_bold(bool) -> None
Font.get_bold() -> bool
设置和获取文本的粗体状态。
Font.set_italic(bool) -> None
Font.get_italic() -> bool
设置和获取文本的斜体状态。
Font.set_direction(direction) -> None
设置文本的呈现方向,direction可选常量值如下:
-
pg.DIRECTION_LTR:从左到右
-
pg.DIRECTION_RTL:从右到左
-
pg.DIRECTION_TTB:从上到下
-
pg.DIRECTION_BTT:从下到上
注意:从上到下和从下到上渲染时,文本中换行符\n效果不佳
Font.metrics(text) -> list
返回一个列表,包含给定文本内容中每个字符的信息。列表包含多个元组,每个元组中是每个字符的最小x偏移量、最大x偏移量、最小y偏移量、最大y偏移量、提前偏移量。无法识别的字符则为None。
Font.get_height() -> int
返回字体的平均高度。
Font.get_ascent() -> int
返回字体上升的高度,即从基线到字符顶端的高度。
Font.get_descent() -> int
返回字体下降的高度,即从基线到字符底部的高度。
6.7 freetype模块索引-字体操作扩展
参考资料:pygame.freetype — pygame-ce v2.4.0 documentation
freetype模块是font模块的扩展,一般用font模块就足够了。
注意:freetype模块没有事先在pygame中导入,所以使用时不能直接调用pg.freetype,而要在开头进行导入:
from pygame import freetype
get_default_font() -> string
获取pygame指定的默认的字体名称。
SysFont(name, size, bold=False, italic=False) -> Font
从系统上调用字体,name为字体名,size为字体大小,bold和italic表示是否设为粗体或斜体。
Font(file, size=0, font_index=0, resolution=0, ucs4=False) -> Font
Font(pathlib.Path) -> Font
从文件载入字体。size是字体的大小,设为0则使用默认大小。font_index是字体位于某个字体文件中的索引。resolution是像素大小,用于缩放字形。
Font.name -> string
字体名称。
Font.path -> string
字体文件路径。
Font.size -> float
Font.size -> (float, float)
字体大小。
Font.ascender -> int
默认大小状态下字体上升高度。
Font.descender -> int
默认大小状态下字体下降高度。
Font.style -> int
字体默认样式。可以通过freetype模块中定义的几个常量(不是locals中的常量)来设定,多个常量之间用按位或"|"操作符连接起来。
Font.underline -> bool
字体默认是否添加下划线。
Font.strong -> bool
字体默认是否加粗
Font.oblique -> bool
字体默认是否倾斜。
Font.wide -> bool
字体默认是否增宽(不支持旋转后的字体)。
Font.strength -> float
字体strong或wide样式中,字形被放大的量。默认值约等于1/36。
Font.underline_adjustment -> float
字体下划线的位置偏移,值的范围是-2.0到2.0之间。默认是1.0。设为0时下划线位于文本基线处,设为负数为上划线,设为正数为下划线。
Font.fixed_sizes -> int
只读属性。字体是否固定宽度。
Font.fixed_sizes -> int
只读属性。字体包含位图字符图像的点大小的数量。
Font.scalable -> bool
只读属性。字体是否可伸缩。
Font.antialiased -> bool
字体是否抗锯齿,默认为True
Font.kerning -> bool
字体是否可调整字距,默认为False。
Font.vertical -> bool
字体是否以垂直方向显示,默认为False。
Font.rotation -> int
字体基线默认的逆时针旋转角度。
Font.fgcolor -> Color
字体前景色,默认为黑色。
Font.bgcolor -> Color
字体背景色,默认为透明色。
Font.get_rect(text, style=STYLE_DEFAULT, rotation=0, size=0) -> rect
返回渲染text文字表面后的矩形对象。矩形对象的大小是表面的大小,位置(x, y)是文本原点的位置(也就是(0, 字体上升高度))。指定rotation将渲染的文字逆时针旋转,size改变字体的大小。
Font.get_metrics(text, size=0) -> [(...), ...]
返回一个列表,包含给定文本内容中每个字符的信息。
Font.get_sized_ascender(<size>=0) -> int
根据字体大小获取字体上升的高度。
Font.get_sized_descender(<size>=0) -> int
根据字体大小获取字体下降的高度。
Font.get_sized_height(<size>=0) -> int
根据字体大小获取字体的平均高度。
Font.get_sized_glyph_height(<size>=0) -> int
根据字体大小获取字体包围框的平均高度。(字体尺寸较小时和get_sized_height返回的结果近似)
Font.get_sizes() -> [(int, int, int, float, float), ...]
Font.get_sizes() -> []
返回嵌入式位图的可用大小。
Font.render(text, fgcolor=None, bgcolor=None, style=STYLE_DEFAULT, rotation=0, size=0) -> (Surface, Rect)
渲染text文本。fgcolor, bgcolor分别表示前景和背景色,style是文本样式,rotation是逆时针旋转角度,size是文本的字体大小。Surface是渲染的文本表面,Rect是文本的大小,位于文字的原点。
text可以设为None,表示重新渲染上一次在get_rect(), render(), render_to(), render_raw(), or render_raw_to()这几个方法调用过的文本。
Font.render_to(surf, dest, text, fgcolor=None, bgcolor=None, style=STYLE_DEFAULT, rotation=0, size=0) -> Rect
将render的运行结果绘制到surf上,位于dest处。
Font.render_raw(text, style=STYLE_DEFAULT, rotation=0, size=0, invert=False) -> (bytes, (int, int))
将渲染的文字以8位灰度值形式返回,前景色为255,背景色为0。
Font.render_raw_to(array, text, dest=None, style=STYLE_DEFAULT, rotation=0, size=0, invert=False) -> Rect
将render_raw的运行结果呈现到一个数组上(二维),位于dest处。
7 按键处理
参考资料:pygame.key — pygame-ce v2.4.0 documentation
pygame.key模块提供了一些处理按键的操作。和键盘相关的event相比,key模块支持了更多的功能,有时比事件更好用。
7.1 获取持续按下的按键
pg.key.get_pressed方法返回一个字典,其中包含每个按键的按下情况。字典的键是按键的标识符常量,是一个整数;字典的值是一个布尔值,表示是否按下了这个按键。只有当按键持续按下,并且没有松开时才会设为True。
上一章的末尾“行走的人”示例中,关于玩家移动是使用event来做的。如果用event,就需要同时处理KEYDOWN和KEYUP事件,判断按键按下且没有松开。但如果使用pg.key.get_pressed,就可以减少麻烦,如下示例:
import pygame as pg
pg.init()
screen = pg.display.set_mode((300, 200))
clock = pg.time.Clock()
image = pg.image.load("logo.png")
image_rect = image.get_rect()
speed = 2
while True:
screen.fill((0, 0, 0))
screen.blit(image, image_rect)
keys = pg.key.get_pressed()
if keys[pg.K_UP]: #如果按下上方向键
image_rect.y -= speed
elif keys[pg.K_DOWN]:
image_rect.y += speed
if keys[pg.K_LEFT]:
image_rect.x -= speed
elif keys[pg.K_RIGHT]:
image_rect.x += speed
for event in pg.event.get():
if event.type == pg.QUIT:
pg.quit()
clock.tick(60)
pg.display.flip()
这样可以很简洁地实现持续移动。
7.2 获取组合键
组合键是指按下多个按键。如果要对按下的多个按键进行处理,可以用pg.key.get_mods()方法。
import pygame as pg
pg.init()
screen = pg.display.set_mode((300, 200))
while True:
mods = pg.key.get_mods()
if mods == pg.KMOD_NONE:
print("无组合键按下")
elif mods & pg.KMOD_CTRL:
print("按下了Ctrl和标识符为", event.key, "的按键")
for event in pg.event.get():
if event.type == pg.QUIT:
pg.quit()
get_mods方法获得的结果类似于event.mods,但是KEYDOWN或KEYUP只会在刚按下和刚松开按键时触发,而get_mods方法获得的是持续按下不松开的按键内容。没有组合键按下时返回pg.KMOD_NONE相同的标识符。
7.3 控制重复触发KEYDOWN事件
pg.key.set_repeat方法可以控制KEYDOWN事件的频率。比如持续按下某个按键时,想要让KEYDOWN事件每过一段时间就触发一次,就可以用set_repeat方法。
set_repeat() -> None
set_repeat(delay) -> None
set_repeat(delay, interval) -> None
如果set_repeat不传递任何参数,那么就是默认的模式,只在按下时触发一次KEYDOWN事件。如果指定了delay参数,那么在按下按键后每经过delay毫秒就重复触发一次KEYDOWN事件。如果同时指定delay和interval参数,那么就表示触发一次KEYDOWN事件,等待delay毫秒后,再以interval毫秒的间隔重复触发KEYDOWN事件。
举例说明:
import pygame as pg
pg.init()
screen = pg.display.set_mode((300, 200))
pg.key.set_repeat(1000, 200)
while True:
for event in pg.event.get():
if event.type == pg.QUIT:
pg.quit()
elif event.type == pg.KEYDOWN:
print("KEYDOWN")
当用户按下某个按键时,会先打印一次"KEYDOWN",然后等待1000ms,再以200ms的时间间隔触发事件,打印多次"KEYDOWN",如果不能理解可以运行代码试一下。
这样的停顿主要应用于更改数值的计数器,当点击增加时数值+1,持续按下时数值增加的速度变快。
7.4 更改文本输入候选框位置
前面介绍TEXTINPUT和TEXTEDITING的时候,已经介绍过在pygame窗口上控制文本输入的方法。现在需要做的是改变文本输入候选框的位置,而不是让其固定在一处。
首先需要了解控制文本输入的两个函数:
pg.key.start_text_input() -> None
pg.key.stop_text_input() -> None
这两个函数分别表示开始文本输入和停止文本输入。
在默认情况下是允许文本输入的,所以一般不需要调用start_text_input。在调用stop_text_input函数后,TEXTINPUT和TEXTEDITING无法被接收到,文本候选框将会持续被隐藏。重启文本输入功能可以再次调用start_text_input函数。
默认情况下,文本候选框是无论输入状态如何都不被显示的。需要显示文本候选框,可以调用下面的代码。
import os
os.environ["SDL_IME_SHOW_UI"] = "1" #显示输入候选框UI
这样的话,当处于允许输入状态下,输入法的文本候选框会在输入时显示。注意要在pg.display.set_mode的前面调用以上代码,否则无效。
注意:文本候选框是指类似于下图的这样一个窗口,即IME,不同输入法不一样。
set_text_input_rect()方法控制了输入框的位置,它接受一个Rect对象表示文本候选框的位置(相对于pygame屏幕)。
pg.key.set_text_input_rect(Rect) -> None
示例如下:
import pygame as pg
import os
os.environ["SDL_IME_SHOW_UI"] = "1" #显示输入候选框UI
pg.init()
screen = pg.display.set_mode((300, 200))
font = pg.font.SysFont("simhei", 20)
text = ""
pg.key.set_text_input_rect((0, 0, 0, 0))
while True:
screen.fill((0, 0, 0))
screen.blit(font.render(text, True, (255, 255, 255)), (0, 0)) #绘制文字
for event in pg.event.get():
if event.type == pg.QUIT:
pg.quit()
elif event.type == pg.TEXTINPUT:
text += event.text
pg.key.set_text_input_rect((font.size(text)[0], 0, 0, 0))
elif event.type == pg.KEYDOWN:
if event.key == pg.K_BACKSPACE: #退格键
text = text[:-1]
pg.display.flip()
运行效果:
7.5 key模块索引-按键操作
get_focused() -> bool
判断窗口是否获取输入焦点。
get_pressed() -> bools
以字典形式返回按下且没有松开的按键。
get_mods() -> int
返回当前按下且没有松开的组合键。
set_repeat() -> None
set_repeat(delay) -> None
set_repeat(delay, interval) -> None
控制重复触发KEYDOWN事件
get_repeat() -> (delay, interval)
获取set_repeat设置的值。
name(key, use_compat=True) -> str
通过按键常量(键码)返回键名,未找到则返回空字符串。
key_code(name=string) -> int
通过按键名返回按键常量,示例:
>>> pygame.key.key_code("return") == pygame.K_RETURN
True
>>> pygame.key.key_code("0") == pygame.K_0
True
>>> pygame.key.key_code("space") == pygame.K_SPACE
True
start_text_input() -> None
开始键盘输入。
stop_text_input() -> None
结束键盘输入。
set_text_input_rect(Rect) -> None
设置IME的位置。
8 鼠标处理
参考资料:
pygame.mouse — pygame-ce v2.4.0 documentation
pygame.cursors — pygame-ce v2.4.0 documentation
8.1 获取鼠标位置
关于鼠标操作,包括位置、鼠标按键等一系列操作都位于pygame.mouse模块。其中最常用的方法是pg.mouse.get_pos(),用于返回鼠标相对于pygame屏幕的位置。鼠标位于屏幕外时,无法准确获取鼠标位置。
注意:通过MOUSEMOTION事件也可以获取鼠标位置,但只有在鼠标移动的时候才会触发这个事件。
import pygame as pg
pg.init()
screen = pg.display.set_mode((300, 200))
font = pg.font.SysFont("simhei", 20)
text = ""
while True:
text = "鼠标位置:" + str(pg.mouse.get_pos())
screen.fill((0, 0, 0))
screen.blit(font.render(text, True, (255, 255, 255)), (0, 0)) #绘制文字
for event in pg.event.get():
if event.type == pg.QUIT:
pg.quit()
pg.display.flip()
运行效果:
8.2 隐藏和显示光标
set_visible方法设置鼠标的可见性。当设为False时,光标在屏幕内时会隐藏不可见。
pg.mouse.set_visible(bool) -> bool
8.3 光标样式
光标可以更改样式,首先需要创建一个pg.cursor.Cursor光标对象。
创建光标对象的方式主要有这几种:通过Surface对象、通过xbm文件、通过光标字符串、通过光标常量载入系统光标。然后通过pg.mouse.set_cursor方法设置样式。
先介绍载入系统光标的方式。只需要将光标样式常量传递给set_cursor方法。pygame模块中有以下用于光标样式的常量。
常量 |
样式描述 |
SYSTEM_CURSOR_ARROW |
箭头 |
SYSTEM_CURSOR_IBEAM |
提示光标输入的工形标 |
SYSTEM_CURSOR_WAIT |
等待 |
SYSTEM_CURSOR_CROSSHAIR |
十字形 |
SYSTEM_CURSOR_WAITARROW |
较小的等待箭头 |
SYSTEM_CURSOR_SIZENWSE |
左上至右下的双向箭头 |
SYSTEM_CURSOR_SIZENESW |
左下至右上的双向箭头 |
SYSTEM_CURSOR_SIZEWE |
左右方向的双向箭头 |
SYSTEM_CURSOR_SIZENS |
上下方向的双向箭头 |
SYSTEM_CURSOR_SIZEALL |
四个方向的箭头 |
SYSTEM_CURSOR_NO |
禁止的符号 |
SYSTEM_CURSOR_HAND |
手的形状,提示点击 |
例如:
pg.mouse.set_cursor(pg.SYSTEM_CURSOR_HAND)
还可以通过Surface对象设置光标样式,这样就可以把某一张图片设为光标。所需的参数是光标热点的位置和表面对象。例如:
pg.mouse.set_cursor((0, 0), pg.image.load("cursor.png"))
8.4 mouse模块索引-鼠标操作
get_pressed(num_buttons=3) -> (button1, button2, button3)
get_pressed(num_buttons=5) -> (button1, button2, button3, button4, button5)
获取各个鼠标按键的按下状态。默认情况下只支持左键、中键、右键,也可以支持鼠标侧面两个按键。
get_pos() -> (x, y)
获取鼠标位置,相对于pygame屏幕。
get_rel() -> (x, y)
获取鼠标位置,相对于于上一次鼠标位置。
set_pos([x, y]) -> None
设置鼠标位置。
set_visible(bool) -> bool
设置鼠标可见性。
get_visible() -> bool
获取鼠标可见性。
get_focused() -> bool
判断窗口是否在获取鼠标输入。
set_cursor(pygame.cursors.Cursor) -> None
set_cursor(size, hotspot, xormasks, andmasks) -> None
set_cursor(hotspot, surface) -> None
set_cursor(constant) -> None
设置鼠标样式。
get_cursor() -> pygame.cursors.Cursor
获取鼠标样式。
8.5 cursor模块索引-光标样式
compile(strings, black='X', white='.', xor='o') -> data, mask
编译光标字符串。下面是一个光标字符串的示例(箭头光标)。
thickarrow_strings = ( #sized 24x24
"XX ",
"XXX ",
"XXXX ",
"XX.XX ",
"XX..XX ",
"XX...XX ",
"XX....XX ",
"XX.....XX ",
"XX......XX ",
"XX.......XX ",
"XX........XX ",
"XX........XXX ",
"XX......XXXXX ",
"XX.XXX..XX ",
"XXXX XX..XX ",
"XX XX..XX ",
" XX..XX ",
" XX..XX ",
" XX..XX ",
" XXXX ",
" XX ",
" ",
" ",
" ")
load_xbm(cursorfile) -> cursor_args
load_xbm(cursorfile, maskfile) -> cursor_args
加载xbm格式的位图文件作为光标。返回的cursor_args可以直接解包传递给set_cursor方法。
Cursor(size, hotspot, xormasks, andmasks) -> Cursor
Cursor(hotspot, surface) -> Cursor
Cursor(constant) -> Cursor
Cursor(Cursor) -> Cursor
Cursor() -> Cursor
光标对象。
Cursor.type -> string
光标类型,可能是"system", "bitmap", "color"
Cursor.data -> tuple
光标数据
Cursor.copy() -> Cursor
复制光标对象
实战:键盘输入程序
本章是实战练习环节,将实现以下效果。文章来源:https://www.toymoban.com/news/detail-444355.html
完整代码
import pygame as pg
from pygame.locals import * #导入所有常量
import os
os.environ["SDL_IME_SHOW_UI"] = "1" #显示输入候选框UI
pg.init()
screen = pg.display.set_mode((300, 300), RESIZABLE) #窗口可调整大小
font = pg.font.SysFont("simhei", 20)
text = ""
index = 0
index_tip = ""
show_index = True
pg.key.set_repeat(750, 25) #持续触发退格键
pg.key.set_text_input_rect((0, 0, 0, 0))
pg.mouse.set_cursor(SYSTEM_CURSOR_IBEAM)
pg.time.set_timer(USEREVENT, 500) #重复生成事件,光标闪烁
def split_text(text): #将字符分行
res = [""]
for char in text:
if font.size(res[-1]+char)[0] > screen.get_width(): #get_width返回表面宽度
res.append("")
else:
res[-1] += char
return res
while True:
screen.fill((0, 0, 0))
s_list = split_text(text)
length = 0
for i, s in enumerate(s_list):
if length != -1:
length += len(s)
if length >= index - i:
index_line = i
idx = index - sum([len(s) for s in s_list[:i]])
s = s[:idx] + index_tip + s[idx:]
length = -1
pg.key.set_text_input_rect((font.size(s[:idx] + "|")[0], i *24, 0, 0))
screen.blit(font.render(s, True, (255, 255, 255)), (0, i * 24))
for event in pg.event.get():
if event.type == QUIT:
pg.quit()
elif event.type == WINDOWFOCUSLOST: #窗口失去焦点,隐藏输入光标
show_index = False
elif event.type == WINDOWFOCUSGAINED: #窗口获取焦点,显示输入光标
show_index = True
elif event.type == TEXTINPUT: #文本输入
text = text[:index] + event.text + text[index:]
index += len(event.text)
elif event.type == KEYDOWN:
if event.key == K_BACKSPACE: #退格键
index -= 1
if index < 0:
index = 0
else:
text = text[:index] + text[index+1:]
elif event.key == K_DELETE: #向右删除键
text = text[:index] + text[index+1:]
elif event.key == K_LEFT: #光标向左
index -= 1
if index < 0:
index = 0
elif event.key == K_RIGHT: #光标向右
index += 1
if index > len(s_list[index_line]):
index -= 1
elif event.type == USEREVENT: #更新光标
if show_index:
index_tip = " " if index_tip != " " else "|"
else:
index_tip = "|"
pg.display.flip()
下一篇文章
Python pygame(GUI编程)模块最完整教程(3)_pygame教程pdf_Python-ZZY的博客-CSDN博客文章来源地址https://www.toymoban.com/news/detail-444355.html
到了这里,关于Python pygame(GUI编程)模块最完整教程(2)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!