赞
踩
上一篇文章:
Python pygame(GUI编程)模块最完整教程(1)_pygame模块详解_Python-ZZY的博客-CSDN博客
总目录:
README.md · Python-ZZY/Python-Pygame最完整教程 - Gitee.com
参考资料:pygame.font — pygame-ce v2.4.0 documentation
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)
加载字体后,下一步是渲染字体。渲染字体调用字体对象的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对象,但每个对象都是一样渲染结果。
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()
注意: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)
注意: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()
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
返回字体下降的高度,即从基线到字符底部的高度。
参考资料: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处。
参考资料:pygame.key — pygame-ce v2.4.0 documentation
pygame.key模块提供了一些处理按键的操作。和键盘相关的event相比,key模块支持了更多的功能,有时比事件更好用。
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()
这样可以很简洁地实现持续移动。
组合键是指按下多个按键。如果要对按下的多个按键进行处理,可以用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相同的标识符。
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,持续按下时数值增加的速度变快。
前面介绍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()
运行效果:
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的位置。
参考资料:
pygame.mouse — pygame-ce v2.4.0 documentation
pygame.cursors — pygame-ce v2.4.0 documentation
关于鼠标操作,包括位置、鼠标按键等一系列操作都位于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()
运行效果:
set_visible方法设置鼠标的可见性。当设为False时,光标在屏幕内时会隐藏不可见。
-
- pg.mouse.set_visible(bool) -> bool
光标可以更改样式,首先需要创建一个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"))
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
获取鼠标样式。
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
复制光标对象
本章是实战练习环节,将实现以下效果。
-
- 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博客
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。