0
def InputBox():
    font = pygame.font.Font(None, 32)

    inputBox = pygame.Rect(50, 50, 140, 32)
    colourInactive = pygame.Color('lightskyblue3')
    colourActive = pygame.Color('dodgerblue2')
    colour = colourInactive
    text = ''

    active = False
    isBlue = True

    while True:
        for event in pg.event.get():
            if event.type == pg.QUIT:
                pg.quit()
                sys.exit()
            if event.type == pygame.MOUSEBUTTONDOWN:
                    if inputBox.collidepoint(event.pos):
                        active = not active
                    else:
                        active = False
                    colour = colourActive if active else colourInactive
            if event.type == pygame.KEYDOWN:
                if active:
                    if event.key == pygame.K_RETURN:
                        print(text)
                        text = ''
                    elif event.key == pygame.K_BACKSPACE:
                        text = text[:-1]
                    else:
                        text += event.unicode

        screen.fill(screenGray)

        txtSurface = font.render(text, True, colour)
        width = max(200, txtSurface.get_width()+10)
        inputBox.w = width
        screen.blit(txtSurface, (inputBox.x+5, inputBox.y+5))
        pygame.draw.rect(screen, colour, inputBox, 2)

        if isBlue:
            color = (0, 128, 255)
        else:
            color = (255, 100, 0)

        pg.display.flip()
        clock.tick(60)

InputBox()

Above is a working function to make a screen that has a text box on it. Now, how would you make two text boxes on the same screen, without just copying and pasting the same code twice?

My idea is that the text box that is clicked on, or activated, will do the stuff in the event part, so you don't have to repeat it all twice. However, I have no idea how to implement that.

Thanks in advance

2 Answers 2

2

You could create a class, and instantiate it as many times as you need different input boxes.

something like this:

# pseudocode #

class InputBox(pygame.Rect):
    def __init__(self, position=(50, 50, 140, 32), 
                 font=pygame.font.Font(None, 32), 
                 color_inactive=pygame.Color('lightskyblue3'),
                 color_active=pygame.Color('dodgerblue2'),
                 text = '',
                 active=False)
        super().__init__(position)    #<- this may need to be adjusted to pygame Rect specs
        self.font = font
        self.color_inactive = color_inactive
        self.color_active = color_active
        self.color = color_inactive
        self.text = text
        self.active = active
Sign up to request clarification or add additional context in comments.

Comments

1

You can create class with methods which draws it and which handle events. And then you can use it many times

Full working example

import pygame

class InputBox():

    def __init__(self, x, y):

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

        self.inputBox = pygame.Rect(x, y, 140, 32)

        self.colourInactive = pygame.Color('lightskyblue3')
        self.colourActive = pygame.Color('dodgerblue2')
        self.colour = self.colourInactive

        self.text = ''

        self.active = False
        self.isBlue = True

    def handle_event(self, event):

        if event.type == pygame.MOUSEBUTTONDOWN:
            self.active = self.inputBox.collidepoint(event.pos)
            self.colour = self.colourActive if self.active else self.colourInactive
        if event.type == pygame.KEYDOWN:
            if self.active:
                if event.key == pygame.K_RETURN:
                    print(self.text)
                    self.text = ''
                elif event.key == pygame.K_BACKSPACE:
                    self.text = self.text[:-1]
                else:
                    self.text += event.unicode

    def draw(self, screen):
        txtSurface = self.font.render(self.text, True, self.colour)
        width = max(200, txtSurface.get_width()+10)
        self.inputBox.w = width
        screen.blit(txtSurface, (self.inputBox.x+5, self.inputBox.y+5))
        pygame.draw.rect(screen, self.colour, self.inputBox, 2)

        if self.isBlue:
            self.color = (0, 128, 255)
        else:
            self.color = (255, 100, 0)

# --- main ---

def mainloop():

    # create objects    
    input1 = InputBox(50, 50)
    input2 = InputBox(450, 50)

    clock = pygame.time.Clock()

    while True:

        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                pygame.quit()
                sys.exit()

            # handle every event
            input1.handle_event(event)
            input2.handle_event(event)

        screen.fill((128,128, 128))

        # draw it
        input1.draw(screen)
        input2.draw(screen)

        pygame.display.flip()
        clock.tick(60)


pygame.init()        
screen = pygame.display.set_mode((800,600))
mainloop()

BTW: for more inputs you could keep them on list (like in GUI frameworks)

def mainloop():

    widgets = [
        InputBox(50, 50),
        InputBox(450, 50),
        InputBox(50, 150),
        InputBox(450, 150),
        InputBox(50, 250),
        InputBox(450, 250),
        InputBox(50, 350),
        InputBox(450, 350),
    ]

    clock = pygame.time.Clock()

    while True:

        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                pygame.quit()
                sys.exit()

            for child in widgets:
                child.handle_event(event)

        screen.fill((128,128, 128))

        for child in widgets:
            child.draw(screen)

        pygame.display.flip()

        clock.tick(60)

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.