Python Forum
Simple pygame input box with cursor and character count - Printable Version

+- Python Forum (https://python-forum.io)
+-- Forum: General (https://python-forum.io/forum-1.html)
+--- Forum: Code sharing (https://python-forum.io/forum-5.html)
+--- Thread: Simple pygame input box with cursor and character count (/thread-40960.html)



Simple pygame input box with cursor and character count - menator01 - Oct-20-2023

# Do the imports
import pygame
from time import time

# Initiate pygame
pygame.init()

# Create the screen surface and window caption
size = (1024, 720)
screen = pygame.display.set_mode(size)
pygame.display.set_caption('Pygame tester')

# Set variable for clock
clock = pygame.time.Clock()

# Set frames per secong
fps = 60

font = pygame.font.Font(None, 32)

class TextBox:
    '''
        TextBox class will create an input box to enter text
        Also provides a header text for the box
    '''
    def __init__(self, header_text):
        # Create our header
        self.head_surface = font.render(header_text, True, 'black')

        # Create input box
        self.rect = pygame.Rect(200, 110, 200, 35)

        # Set a text variable
        self.text = ''

        # Create a text surface
        self.text_surface = font.render(self.text, True, 'black')

        # Get the text rect
        self.text_rect = self.text_surface.get_rect()

        # Create a cursor
        self.cursor = pygame.Rect(self.text_rect.topright, (3, self.text_rect.height))

        # Counter
        self.count_text = pygame.Rect(200, 50, 200, 35)
        self.count_text_surface = font.render('Character Count:', True, 'black')
        

    def draw(self, screen):
        # Draw everthing to the screen

        screen.blit(self.count_text_surface, (50, 80))

        screen.blit(self.head_surface, (50, self.rect.y+8))

        pygame.draw.rect(screen, 'gray85', self.rect)
        screen.blit(self.text_surface, (self.rect.x+5, self.rect.y+6))
        pygame.draw.rect(screen, 'black', self.rect, 1)

        # Give the cursor a blinking effect
        if time() % 1 > 0.5:
            text_rect = self.text_surface.get_rect(topleft=(self.rect.x+5, self.rect.y+6))
            self.cursor.midleft = text_rect.midright
            pygame.draw.rect(screen, 'black', self.cursor)

    def add(self, text):
        # Add text to the input box
        self.text += text

    def delete(self):
        # Remove text from input box
        self.text = self.text[:-1]

    def update(self):
        # Update everything
        self.text_surface = font.render(self.text, True, 'black')
        width = max(200, self.text_surface.get_width()+10)
        self.rect.w = width

        self.count_text_surface = font.render(f'Character Count: ({len(self.text)}). Limit = 50', True, 'black')

    def myevents(self, event):
        # Check pygame events for a key press
        if event.type == pygame.KEYDOWN:

            # If the backspace is pressed remove text
            # Else add the text
            if event.key == pygame.K_BACKSPACE:
                if len(self.text) > 0:
                    self.delete()
            else:
                # Allow only letters, numbers and space in the input box
                if event.unicode.isalnum() or event.key == pygame.K_SPACE:

                    # Limiting only to thre letters
                    if len(self.text) >= 50:
                        self.delete()
                    
                    # Add to input box
                    self.add(event.unicode)
        
                 

# Create the input box
textbox = TextBox('Enter Text:')

# Set pygame loop variable
running = True

# Start the loop
while running:

    # Get pygame events
    event = pygame.event.poll()

    textbox.myevents(event)
    # Exit pygame
    if event.type == pygame.QUIT:
        running = False


    # Update the input box
    textbox.update()

    screen.fill('white')

    # Draw the text box and header
    textbox.draw(screen)
    
    # Update surface
    pygame.display.flip()

    # Set clock speed
    clock.tick(fps)

pygame.quit()