Search code examples
pythoninputpygamekeybackspace

Text input in pygame


I am Trying to make a text input function in pygame and i almost made it but there is a problem.

If a press the Backspace key for how much time it only deletes one charecter it deletes another charecter only if i realease and again press the backspace key.

It is possible for me to press the backspace key once and it continuosly deletes charecters every half a second until i realease the backspace key.

Here's my text input function code but the function is not completely done.

def text_input(x, y, color, char=None, char_x=None, char_y=None, fill=(0, 0, 0), thing=None):
    """

    :param x: Defines the x axis or the width position where the text input should be drawn.
    :param y: Defines the y axis or the height position where the text input should be drawn.
    :param color: Defines the color of the text input.
    :param char: If the parameter char in not entered it does not do anything otherwise it display's the the parameter
                 char's text on the screen
    :param char_x: If the parameter char is entered char_x Defines the x axis or the width position where the text
                   should be drawn.
    :param char_y: If the parameter char is entered char_y Defines the y axis or the height position where the text
                   should be drawn.
    :param fill: If the parameter fill is entered it fills the display with the tuple of the rgb color pixels which the
                 user entered. But if the parameter fill is not entered it fills the display with the rgb color code
                 black.
    :param thing: If the user wants something to been drawn on the display the fill the parameter thing with the object
                  they want to draw. But if the parameter thing is not entered
    :return: It Display's the text input on the window and the updates it
    """

    characters = ""

    while True:
        for detect in pygame.event.get():
            if detect.type == QUIT:
                exit()

            elif detect.type == KEYDOWN:
                if detect.key == K_BACKSPACE:
                    characters = characters[:-1]
                    print(characters)
                elif detect.key == K_RETURN:
                    global text
                    text = characters
                    return

                else:
                    characters = characters + detect.unicode

                WINDOW.fill((0, 0, 0))
                text = FONT.render(f"{characters}", True, color)
                draw(text, x, y, True)

If you want to know my full code here it is:

import pygame
from pygame.locals import *
from win32api import GetSystemMetrics
pygame.init()
WIDTH = GetSystemMetrics(0)
HEIGHT = GetSystemMetrics(1)-64
WIDTH_HEIGHT = (WIDTH, HEIGHT)

WINDOW = pygame.display.set_mode(WIDTH_HEIGHT)
FONT = pygame.font.Font("Password generator font.ttf", 32)
text = ""


def draw(thing, x, y, update=None):
    """

    :param thing: The object what needs to be drawn on the screen
    :param x: Defines the x axis or the width position where the object should be drawn.
    :param y: Defines the y axis or the height position where the object should be drawn.
    :param update: If the parameter update is not passed we don't update the display.
                   But if the parameter update is passed as True we update the display.
    :return: It returns the object on the display at its specific place or it returns
            the object on the display at its specific place and updates and updates the display based on the parameter
            update.
    """

    if update is True:
        WINDOW.blit(thing, (x, y))
        return pygame.display.update()

    else:
        return WINDOW.blit(thing, (x, y))


def text_input(x, y, color, char=None, char_x=None, char_y=None, fill=(0, 0, 0), thing=None):
    """

    :param x: Defines the x axis or the width position where the text input should be drawn.
    :param y: Defines the y axis or the height position where the text input should be drawn.
    :param color: Defines the color of the text input.
    :param char: If the parameter char in not entered it does not do anything otherwise it display's the the parameter
                 char's text on the screen
    :param char_x: If the parameter char is entered char_x Defines the x axis or the width position where the text
                   should be drawn.
    :param char_y: If the parameter char is entered char_y Defines the y axis or the height position where the text
                   should be drawn.
    :param fill: If the parameter fill is entered it fills the display with the tuple of the rgb color pixels which the
                 user entered. But if the parameter fill is not entered it fills the display with the rgb color code
                 black.
    :param thing: If the user wants something to been drawn on the display the fill the parameter thing with the object
                  they want to draw. But if the parameter thing is not entered
    :return: It Display's the text input on the window and the updates it
    """

    characters = ""

    while True:
        for detect in pygame.event.get():
            if detect.type == QUIT:
                exit()

            elif detect.type == KEYDOWN:
                if detect.key == K_BACKSPACE:
                    characters = characters[:-1]
                    print(characters)
                elif detect.key == K_RETURN:
                    global text
                    text = characters
                    return

                else:
                    characters = characters + detect.unicode

                WINDOW.fill((0, 0, 0))
                text = FONT.render(f"{characters}", True, color)
                draw(text, x, y, True)


running = True

while running:
    for event in pygame.event.get():
        if event.type == QUIT:
            exit()

    text_input(0, 0, (255, 255, 255))

Solution

  • Use pygame.key.set_repeat() to control how held keys are repeated:

    When the keyboard repeat is enabled, keys that are held down will generate multiple pygame.KEYDOWN events. [...]

    [...] To disable key repeat call this function with no arguments or with delay set to 0.

    Just call pygame.key.set_repeat() to disable repeating keys. e.g:

    pygame.key.set_repeat(100, 100)