Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I create a text input box with Pygame?

Tags:

I want to get some text input from the user in Python and display what they are typing in a text box, and when they press enter, it gets stored in a string.

I've looked everywhere, but I just can't find anything. I'm using Pygame.

like image 616
Deps Avatar asked Sep 24 '17 12:09

Deps


People also ask

How do you input a text box in Python?

The simplest way to do it is to set an input equal to a variable for later use, and then call the variable later in the program. variable = str(input("Type into the text box."))

How do you draw text in Pygame?

Pygame does not provide a direct way to write text onto a Surface object. The method render() must be used to create a Surface object from the text, which then can be blit to the screen. The method render() can only render single lines. A newline character is not rendered.


1 Answers

You can define a rect as the area of the input box. If a pygame.MOUSEBUTTONDOWN event occurs, use the colliderect method of the input_box rect to check if it collides with the event.pos and then activate it by setting a active variable to True.

If the box is active you can type something and Pygame will generate pygame.KEYDOWN events which have a unicode attribute that you can simply add to a string, e.g. text += event.unicode. If the user presses enter, you can do something with the text string (in the example I just print it) and reset it to ''.

import pygame as pg   def main():     screen = pg.display.set_mode((640, 480))     font = pg.font.Font(None, 32)     clock = pg.time.Clock()     input_box = pg.Rect(100, 100, 140, 32)     color_inactive = pg.Color('lightskyblue3')     color_active = pg.Color('dodgerblue2')     color = color_inactive     active = False     text = ''     done = False      while not done:         for event in pg.event.get():             if event.type == pg.QUIT:                 done = True             if event.type == pg.MOUSEBUTTONDOWN:                 # If the user clicked on the input_box rect.                 if input_box.collidepoint(event.pos):                     # Toggle the active variable.                     active = not active                 else:                     active = False                 # Change the current color of the input box.                 color = color_active if active else color_inactive             if event.type == pg.KEYDOWN:                 if active:                     if event.key == pg.K_RETURN:                         print(text)                         text = ''                     elif event.key == pg.K_BACKSPACE:                         text = text[:-1]                     else:                         text += event.unicode          screen.fill((30, 30, 30))         # Render the current text.         txt_surface = font.render(text, True, color)         # Resize the box if the text is too long.         width = max(200, txt_surface.get_width()+10)         input_box.w = width         # Blit the text.         screen.blit(txt_surface, (input_box.x+5, input_box.y+5))         # Blit the input_box rect.         pg.draw.rect(screen, color, input_box, 2)          pg.display.flip()         clock.tick(30)   if __name__ == '__main__':     pg.init()     main()     pg.quit() 

Here's an object-oriented variant that allows you to easily create multiple input boxes:

import pygame as pg   pg.init() screen = pg.display.set_mode((640, 480)) COLOR_INACTIVE = pg.Color('lightskyblue3') COLOR_ACTIVE = pg.Color('dodgerblue2') FONT = pg.font.Font(None, 32)   class InputBox:      def __init__(self, x, y, w, h, text=''):         self.rect = pg.Rect(x, y, w, h)         self.color = COLOR_INACTIVE         self.text = text         self.txt_surface = FONT.render(text, True, self.color)         self.active = False      def handle_event(self, event):         if event.type == pg.MOUSEBUTTONDOWN:             # If the user clicked on the input_box rect.             if self.rect.collidepoint(event.pos):                 # Toggle the active variable.                 self.active = not self.active             else:                 self.active = False             # Change the current color of the input box.             self.color = COLOR_ACTIVE if self.active else COLOR_INACTIVE         if event.type == pg.KEYDOWN:             if self.active:                 if event.key == pg.K_RETURN:                     print(self.text)                     self.text = ''                 elif event.key == pg.K_BACKSPACE:                     self.text = self.text[:-1]                 else:                     self.text += event.unicode                 # Re-render the text.                 self.txt_surface = FONT.render(self.text, True, self.color)      def update(self):         # Resize the box if the text is too long.         width = max(200, self.txt_surface.get_width()+10)         self.rect.w = width      def draw(self, screen):         # Blit the text.         screen.blit(self.txt_surface, (self.rect.x+5, self.rect.y+5))         # Blit the rect.         pg.draw.rect(screen, self.color, self.rect, 2)    def main():     clock = pg.time.Clock()     input_box1 = InputBox(100, 100, 140, 32)     input_box2 = InputBox(100, 300, 140, 32)     input_boxes = [input_box1, input_box2]     done = False      while not done:         for event in pg.event.get():             if event.type == pg.QUIT:                 done = True             for box in input_boxes:                 box.handle_event(event)          for box in input_boxes:             box.update()          screen.fill((30, 30, 30))         for box in input_boxes:             box.draw(screen)          pg.display.flip()         clock.tick(30)   if __name__ == '__main__':     main()     pg.quit() 

There are also third party modules available like pygame_textinput.

like image 170
skrx Avatar answered Oct 23 '22 16:10

skrx