将用户文本输入到屏幕

时间:2017-08-15 13:42:35

标签: python pygame

我想将用户输入的文本blit到屏幕上。每次用户按下Return键时,键入的文本应该显示在屏幕上。对于文本输入,我使用[text_input module](https://github.com/Nearoo/pygame-text-input)。

这是我到目前为止提出的代码:

import pygame_textinput
import pygame
pygame.init()

# Set some parameters
duration = 5.0
time = pygame.time.get_ticks()/1000

screen = pygame.display.set_mode((400, 400))
clock = pygame.time.Clock()

yoffset = 5
# Function that positions user input rects on screen
def renderInput(text, xoffset, yoffset):
    font = pygame.font.SysFont("arial", 20)
    renderText = font.render(text, False, (0, 0, 0))
    rectText = renderText.get_rect()
    rectText = rectText.move((0 + xoffset),  (screen.get_height()/2 + yoffset))
    return  renderText, rectText

# Fills the screen once at the beginning
screen.fill((225, 225, 225))

while (pygame.time.get_ticks()/1000) < time + duration:
    # creat new text input object on every trial
    textinput = pygame_textinput.TextInput()

    while True:
        # Fills the surface after each keypress
        screen.fill((225, 225, 225))

        # Check events
        events = pygame.event.get()
        for event in events:
            if event.type == pygame.QUIT:
                exit()

        # Feed with events every frame
        # This evaluates to True once Return is pressed
        if textinput.update(events):
            userInput = textinput.get_text()
            yoffset += 20
            break

        # Blit surface onto the screen
        screen.blit(textinput.get_surface(), (10, 10))
        # Update screen
        pygame.display.update()
        clock.tick(30)

    # Blits user input to screen each time "Return" is pressed
    # First get input text and the rectangle of the text
    text, textrect = renderInput(userInput, 5, yoffset)
    # Then blit it to the screen
    screen.blit(text, textrect)
    pygame.display.update()

我的问题是,只有在处理输入的while循环中的每次按键后我都没有填满屏幕时,blitting才有效。如果我这样做,那么每次用户按下Return键后,文本输入都不会被清除。

所以有两种方法可以同时使用,在每次按键后重绘并在每次按下Return后显示下面的文字。

感谢。

2 个答案:

答案 0 :(得分:1)

如果我理解正确的话,应该清除输入字段中的文本,并且它应该在屏幕的主区域中显示为blit。如果用户按Enter键,我会将文本分配给user_input变量,然后创建一个新的pygame_textinput.TextInput()实例以清除输入字段。

我试图简化您的代码,因为两个while循环有点混乱,我不确定它们的用途是什么。游戏中通常只应有一个while循环。

import pygame
import pygame_textinput


pygame.init()

screen = pygame.display.set_mode((400, 400))
clock = pygame.time.Clock()
font = pygame.font.SysFont("arial", 20)

textinput = pygame_textinput.TextInput()
user_input = ''

done = False

while not done:
    events = pygame.event.get()
    for event in events:
        if event.type == pygame.QUIT:
            done = True

    if textinput.update(events):
       user_input = textinput.get_text()
       textinput = pygame_textinput.TextInput()

    # Draw everything.
    screen.fill((225, 225, 225))

    screen.blit(textinput.get_surface(), (10, 10))

    user_input_surface = font.render(user_input, True, (30, 80, 100))
    screen.blit(user_input_surface, (10, 50))

    pygame.display.update()
    clock.tick(30)

pygame.quit()

编辑:在这个版本中,我将渲染的文本表面附加到列表中并用偏移量对它们进行blit。

import pygame
import pygame_textinput


pygame.init()

screen = pygame.display.set_mode((400, 400))
clock = pygame.time.Clock()
font = pygame.font.SysFont("arial", 20)

textinput = pygame_textinput.TextInput()
user_inputs = []

done = False

while not done:
    events = pygame.event.get()
    for event in events:
        if event.type == pygame.QUIT:
            done = True

    if textinput.update(events):
       user_inputs.append(
           font.render(textinput.get_text(), True, (30, 80, 100)))
       textinput = pygame_textinput.TextInput()

    screen.fill((225, 225, 225))

    screen.blit(textinput.get_surface(), (10, 10))

    for y, text_surf in enumerate(user_inputs):
        screen.blit(text_surf, (10, 50+30*y))

    pygame.display.update()
    clock.tick(30)

pygame.quit()

Edit2:要获取表格,您可以使用modulo作为列偏移的行偏移和楼层划分。这个例子的问题是如果文本表面太宽,它们可能会重叠。

for n, text_surf in enumerate(user_inputs):
    # 5 rows. Offset = 30 pixels.
    y_pos = 50 + (n%5) * 30
    # After 5 rows add a new column. Offset = 100 pixels.
    x_pos = 10 + n // 5 * 100
    screen.blit(text_surf, (x_pos, y_pos))

答案 1 :(得分:1)

我编辑了包含您建议的代码。非常感谢,这似乎解决了我的问题。这是包含计时器的当前版本:

import pygame_textinput
import pygame
pygame.init()

# Set some parameters
duration = 5.0
time = pygame.time.get_ticks()/1000
xoffset = 5
yoffset = 5

screen = pygame.display.set_mode((400, 400))
font = pygame.font.SysFont("arial", 20)
clock = pygame.time.Clock()

# Creates textinput instance and an empty list to store inputs
textinput = pygame_textinput.TextInput()
userInputs = []

# Fills the screen once at the beginning
screen.fill((225, 225, 225))

while (pygame.time.get_ticks()/1000) < time + duration:

    # Check events
    events = pygame.event.get()
    for event in events:
        if event.type == pygame.QUIT:
            exit()

    # Feed with events every frame
    # This evaluates to True once Return is pressed
    if textinput.update(events):
        userInputs.append(font.render(textinput.get_text(), True, (30, 80, 100)))
        textinput = pygame_textinput.TextInput()

    # Fill screen
    screen.fill((225, 225, 225))
    # Blit its surface onto the screen
    screen.blit(textinput.get_surface(), (screen.get_rect().centerx, screen.get_rect().height/5))

    for y, text_surf in enumerate(userInputs):
            screen.blit(text_surf, (10, (screen.get_rect().height/4)+30*y))

    # Update screen
    pygame.display.update()
    clock.tick(30)

我不想打扰你,但现在还有一个问题,我无法解决问题。一旦退出屏幕的下边框,是否可以在第二列中呈现文本输入?因此,例如,如果用户键入了许多不适合的单词,是否可以将下一个文本输入移到右侧并使其从第一个输入旁边开始(创建第二个列可以说)。感谢你的帮助到目前为止,我真的很高兴。