How to make a button in Pygame updated to 26.8.2021

Recap: doing code for buttons in pygame.

Today I added a new style and a way to customize also the hovering colors of the button that now can be different for each one or be left as it is by default.

screen

Video:

https://pythonprogramming.altervista.org/wp-content/uploads/2021/08/26082021.mp4

Code:

import pygame
import pygame.gfxdraw


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

buttons = pygame.sprite.Group()

class Button(pygame.sprite.Sprite):
    def __init__(self, screen, position, text, size,
        colors="white on blue",
        hover_colors="red on green",
        style=1, borderc=(255,255,255)):
        # the hover_colors attribute needs to be fixed
        super().__init__()
        self.text = text
        # --- colors ---
        self.colors = colors
        self.original_colors = colors
        self.hover_colors = hover_colors
        self.fg, self.bg = self.colors.split(" on ")
        self.style = style
        self.borderc = borderc # for the style2
        # font
        self.font = pygame.font.SysFont("Arial", size)
        self.render()
        self.x, self.y, self.w , self.h = self.text_render.get_rect()
        self.x, self.y = position
        self.rect = pygame.Rect(self.x, self.y, self.w, self.h)
        self.position = position
        self.pressed = 1
        buttons.add(self)

    def render(self):
        self.text_render = self.font.render(self.text, 1, self.fg)
        self.image = self.text_render

    def update(self):
        self.fg, self.bg = self.colors.split(" on ")
        if self.style == 1:
            self.draw_button1()
        elif self.style == 2:
            self.draw_button2()
        self.hover()
        self.click()

    def draw_button1(self):
        ''' draws 4 lines around the button and the background '''
        # horizontal up
        pygame.draw.line(screen, (150, 150, 150), (self.x, self.y), (self.x + self.w , self.y), 5)
        pygame.draw.line(screen, (150, 150, 150), (self.x, self.y - 2), (self.x, self.y + self.h), 5)
        # horizontal down
        pygame.draw.line(screen, (50, 50, 50), (self.x, self.y + self.h), (self.x + self.w , self.y + self.h), 5)
        pygame.draw.line(screen, (50, 50, 50), (self.x + self.w , self.y + self.h), [self.x + self.w , self.y], 5)
        # background of the button
        pygame.draw.rect(screen, self.bg, (self.x, self.y, self.w , self.h))  

    def draw_button2(self):
        ''' a linear border '''
        pygame.draw.rect(screen, self.bg, (self.x, self.y, self.w , self.h))
        pygame.gfxdraw.rectangle(screen, (self.x, self.y, self.w , self.h), self.borderc)

    def hover(self):
        ''' checks if the mouse is over the button and changes the color if it is true '''
        if self.rect.collidepoint(pygame.mouse.get_pos()):
            # you can change the colors when the pointer is on the button if you want
            self.colors = self.hover_colors
        else:
            self.colors = self.original_colors
        self.render()

    def click(self):
        ''' checks if you click on the button and makes the call to the action just one time'''
        if self.rect.collidepoint(pygame.mouse.get_pos()):
            if pygame.mouse.get_pressed()[0] and self.pressed == 1:
                print(self.position)
                print(self.colors)
                print(self.hover_colors)
                print(self.fg)
                print(self.bg)
                self.pressed = 0
            if pygame.mouse.get_pressed() == (0,0,0):
                self.pressed = 1


def loop():
    while True:
        for event in pygame.event.get():
            if (event.type == pygame.QUIT):
                pygame.quit()
            if event.type == pygame.KEYDOWN:
                if event.key == pygame.K_ESCAPE:
                    pygame.quit()

        buttons.update()
        buttons.draw(screen)
        clock.tick(60)
        pygame.display.update()
    pygame.quit()
# BUTTONS ISTANCES
b0 = Button(screen, (10, 10), "1st button", 55, "black on white")
b1 = Button(screen, (10, 100), "2nd button", 40, "black on red")
b2 = Button(screen, (10, 170), "3rd button", 36, "red on yellow", hover_colors="white on red", style=2, borderc=(255,255,0))
print(b0.x)

loop()

Repository: https://github.com/formazione/pygame_button

Let’s make button.py as a module

Let’s make button.py as a module

Now I want to put the buttons code outside of the main function to stay more organized

import pygame

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

buttons = pygame.sprite.Group()

class Button(pygame.sprite.Sprite):
    def __init__(self, screen, position, text, size,
        colors="white on blue",
        hover_colors="red on green"):
        # the hover_colors attribute needs to be fixed
        super().__init__()
        self.text = text
        self.colors = colors
        self.original_colors = colors
        self.hover_colors = hover_colors
        self.fg, self.bg = self.colors.split(" on ")
        self.font = pygame.font.SysFont("Arial", size)
        self.text_render = self.font.render(self.text, 1, self.fg)
        self.image = self.text_render
        self.x, self.y, self.w , self.h = self.text_render.get_rect()
        self.x, self.y = position
        self.rect = pygame.Rect(self.x, self.y, self.w, self.h)
        self.position = position
        self.pressed = 1
        buttons.add(self)

    def update(self):
        self.fg, self.bg = self.colors.split(" on ")
        self.draw_button()
        self.hover()
        self.click()

    def draw_button(self):
        ''' draws 4 lines around the button and the background '''
        pygame.draw.line(screen, (150, 150, 150), (self.x, self.y), (self.x + self.w , self.y), 5)
        pygame.draw.line(screen, (150, 150, 150), (self.x, self.y - 2), (self.x, self.y + self.h), 5)
        pygame.draw.line(screen, (50, 50, 50), (self.x, self.y + self.h), (self.x + self.w , self.y + self.h), 5)
        pygame.draw.line(screen, (50, 50, 50), (self.x + self.w , self.y + self.h), [self.x + self.w , self.y], 5)
        pygame.draw.rect(screen, self.bg, (self.x, self.y, self.w , self.h))

    def hover(self):
        ''' checks if the mouse is over the button and changes the color if it is true '''
        if self.rect.collidepoint(pygame.mouse.get_pos()):
            self.colors = self.hover_colors
        else:
            self.colors = self.original_colors

    def click(self):
        ''' checks if you click on the button and makes the call to the action just one time'''
        if self.rect.collidepoint(pygame.mouse.get_pos()):
            if pygame.mouse.get_pressed()[0] and self.pressed == 1:
                print(self.position)
                self.pressed = 0
            if pygame.mouse.get_pressed() == (0,0,0):
                self.pressed = 1


def loop():
    while True:
        for event in pygame.event.get():
            if (event.type == pygame.QUIT):
                pygame.quit()
            if event.type == pygame.KEYDOWN:
                if event.key == pygame.K_ESCAPE:
                    pygame.quit()

        buttons.update()
        buttons.draw(screen)
        clock.tick(60)
        pygame.display.update()
    pygame.quit()
# BUTTONS ISTANCES
b0 = Button(screen, (10, 10), "1st button", 55, "black on white")
b1 = Button(screen, (10, 100), "2nd button", 40, "black on red")
b2 = Button(screen, (10, 200), "3rd button", 36, "red on yellow")
print(b0.x)

loop()

I will import this module in the main function that now looks like this

import pygame
import pygame.gfxdraw
from buttons import *

pygame.init()


def loop():
    while True:
        for event in pygame.event.get():
            if (event.type == pygame.QUIT):
                pygame.quit()
            if event.type == pygame.KEYDOWN:
                if event.key == pygame.K_ESCAPE:
                    pygame.quit()

        buttons.update()
        buttons.draw(screen)
        clock.tick(60)
        pygame.display.update()
    pygame.quit()

# BUTTONS ISTANCES
b0 = Button((10, 10), "Click", 55, "black on white")
b1 = Button((10, 100), "Run", 40, "black on red")

b2 = Button((10, 170), "Save", 36, "red on yellow",
    hover_colors="blue on orange", style=2, borderc=(255,255,0))

loop()

Here we find the three istances of the button.

In the next post we will see new features like:

See ya soon then.

Repo: https://github.com/formazione/pygame_button.git


Subscribe to the newsletter for updates
Tkinter templates
My youtube channel

Twitter: @pythonprogrammi - python_pygame

Videos

Speech recognition game

Pygame's Platform Game

Other Pygame's posts