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.
Video:
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:
- adding a command
- change the cursor when hover
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