Python Forum
Pygame and buttons play
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Pygame and buttons play
#1
Just playing around with making buttons in pygame and thought I would share

btn_class.py
import pygame

# Inialize pygame font
pygame.font.init()

# Create a sprite group
btn_sprites = pygame.sprite.Group()

class Button(pygame.sprite.Sprite):
    def __init__(self, x=0, y=0, text='Button'):
        pygame.sprite.Sprite.__init__(self)

        # Set Button Attributes
        self.border_color = '#999999'
        self.bgcolor = 'blue'
        self.fgcolor = 'white'
        self.bg_hover_color = 'mediumblue'
        self.fg_hover_color = 'cyan'
        self.text = text
        self.x = x
        self.y = y
        self.type = None
        self.function = None

        # These two lines should not be changed
        self.pointer = pygame.mouse.get_pos()
        self.cursor = False
        
        # Setup the font and button text
        self.font = pygame.font.SysFont(None, 35)
        self.btn_text = self.font.render(self.text, True, self.fgcolor)

        # Get text width and height
        self.text_width, self.text_height = self.font.size(str(self.text))

        # Create the button surface
        self.button = pygame.Surface((self.text_width*2, self.text_height*2))
        self.button.fill(self.bgcolor)

        # Get button size
        self.button_rect = self.button.get_rect()

        # Get the center to place button text
        self.center_text = (
            self.button_rect.width/2 - self.text_width/2,
            self.button_rect.height/2 - self.text_height/2
        )

        # Blit text to button
        self.button.blit(self.btn_text, self.center_text)

        # Create the shadow image
        self.image = pygame.Surface((self.button_rect.width+5, self.button_rect.height+5)).convert()
        self.image.fill(self.border_color)
        self.rect = self.image.get_rect()
        self.image.set_alpha(200)

        # Get the center for button and shadow
        self.center_button = (
            self.rect.width/2 - self.button_rect.width/2,
            self.rect.height/2 - self.button_rect.height/2
        )

        # Add Button to sprite group
        btn_sprites.add(self)
        

    def update(self):
        ''' Method for updating button effects '''

        # Place the button
        self.rect.x = self.x
        self.rect.y = self.y

        # Get the pointer position
        self.pointer = pygame.mouse.get_pos()

        # If the pointer hovers over a button make highlight effect
        if self.rect.collidepoint(self.pointer):
            self.image.set_alpha(220)
            self.button.fill(self.bg_hover_color)

            # Effects for mouse click
            if pygame.mouse.get_pressed()[0] and self.function != None:
                self.image.set_colorkey(self.border_color)
                self.image.set_alpha(255)
            else:
                # Reset shadow
                self.image.set_colorkey()
        else:
            # Reset the button to default
            self.image.set_alpha(200)
            self.button.fill(self.bgcolor)

        # Update the button
        self.button.blit(self.btn_text, self.center_text)
        self.image.blit(self.button, self.center_button)
buttons.py

import pygame
from btn_class import Button, btn_sprites

# Setup pygame window
window_size = (1280, 780)
window = pygame.display.set_mode(window_size)

# Pygame caption
pygame.display.set_caption('My PyGame Window')

# Setup clock
clock = pygame.time.Clock()
fps = 60

# Window color
window_color = '#ffffff'

# Some flags
running = True
cursor = False
text = ''

# Create a sprite group
# This group is for displaying buttons only
allsprites = pygame.sprite.Group()

# Create some buttons
'''
    Button attributes with defaults:
        border_color = '#999999'
        bgcolor = 'blue'
        fgcolor = 'white'
        bg_hover_color = 'mediumblue'
        fg_hover_color = 'cyan'
        text = text
        x = x
        y = y
        type = None
        function = None
'''

def draw_text(text=None):
    '''
        Function will draw text to window
    '''
    font = pygame.font.SysFont(None, 40)
    string = font.render(text, True, 'black')
    string_width, string_height = font.size(str(text))
    window_width, window_height = window.get_rect().width, window.get_rect().height
    
    center = (
        window_width/2 - string_width/2,
        window_height/2 - string_height/2
    )
    
    window.blit(string, center)


btn1 = Button()
btn1.x = 20
btn1.y = 20
btn1.function = lambda: draw_text(f'You clicked {btn1.text.capitalize()}')

btn2 = Button(text='Button 2')
btn2.x = 220
btn2.y = 20
btn2.bgcolor = 'orange'
btn2.bg_hover_color = 'orangered'
btn2.function = lambda: draw_text(f'You clicked {btn2.text.capitalize()}')

btn3 = Button(text='Clear')
btn3.x = 460
btn3.y = 20
btn3.bgcolor = 'tomato'
btn3.bg_hover_color = 'red'
btn3.function = ''
btn3.type = 'clear'

# Add buttons to allsprites group
allsprites.add(btn1, btn2, btn3)

while running:
    window.fill(window_color)

    # Track pygame events
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            running = False

        # loop through btn_sprite group
        for button in btn_sprites:

            # Check for collisions/hover
            if button.rect.collidepoint(button.pointer):

                # We are over a button change pointer to hand
                button.cursor = True

                # Check if mouse button is clicked and we have a function to fire
                # Can add a type here to check for a specific button
                if pygame.mouse.get_pressed()[0] and button.function != None:
                    if button.type == 'clear':
                        text = ''
                    else:
                        text = f'You pressed {button.text}'                 
            else:
                # We are not over a button return pointer to default
                button.cursor = False
                pygame.mouse.set_cursor()

    # Loop through buttons and if flag is True change pointer to hand
    for button in btn_sprites:
        if button.cursor:
            pygame.mouse.set_cursor(pygame.SYSTEM_CURSOR_HAND)

    # Update allsprites and draw to window
    allsprites.update()
    allsprites.draw(window)

    draw_text(text)

    pygame.display.update()
    clock.tick(fps)
I welcome all feedback.
The only dumb question, is one that doesn't get asked.
My Github
How to post code using bbtags


Reply


Forum Jump:

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020