menator01
Gold Coder
Been playing around with creating buttons with pygame and thought I would share.
btn_class.py
button.py
btn_class.py
Python:
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)
button.py
Python:
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)
Last edited: