May-05-2022, 09:26 PM
(This post was last modified: May-05-2022, 09:26 PM by deanhystad.)
Here is a couple of rough pygame classes that act somewhat like Label and Button.
import pygame pygame.init() FOREGROUND_COLOR = "White" BACKGROUND_COLOR = "Black" DEFAULT_FONT = pygame.font.SysFont(None, 32) display = pygame.display.set_mode((300, 300)) screen = pygame.display.set_mode([450, 350]) class Widget(pygame.surface.Surface): """Base class for pygame widgets""" def __init__(self, parent, size, foreground=None): super().__init__(size) self.parent = parent self.foreground = FOREGROUND_COLOR if foreground is None else foreground self.background = BACKGROUND_COLOR self.rect = self.get_rect() def draw(self): """Draw (blit) self on parent surface.""" self.parent.blit(self, (self.rect.x, self.rect.y)) return self def at(self, x, y): """Set upper left corner at x, y""" self.rect.x = x self.rect.y = y return self def center_at(self, x, y): """Set center at x, y""" self.rect.centerx = x self.rect.centery = y return self class Label(Widget): """A tkinter Label like thing for pygame""" def __init__(self, parent, text, width=None, font=None, foreground=None): self.width = len(text) if width is None else width self.font = DEFAULT_FONT if font is None else font size = self.font.render("W"*self.width, True, BACKGROUND_COLOR).get_size() super().__init__(parent, size, foreground) self.set_text(text) def set_text(self, text): self.text = text text_img = self.font.render(self.text, True, self.foreground) y = (self.rect.height - text_img.get_height()) // 2 self.fill(self.background) self.blit(text_img, (0, y)) self.draw() return self class CircleButton(Widget): """A tkinter Button like think for pygame""" buttons = [] @classmethod def clicked(cls, x, y): """Call this method to find what button was pressed""" for button in cls.buttons: if button.click(x, y): return True return False def __init__(self, parent, text, radius, foreground=None, text_color=None, font=None): super().__init__(parent, (radius*2, radius*2), foreground) self.font = DEFAULT_FONT if font is None else font self.text_color = self.background if text_color is None else text_color self.callback = None self.buttons.append(self) self.set_text(text) def set_text(self, text): """Set my label text. Label is centered in button""" self.text = text text_img = self.font.render(self.text, True, self.text_color) x = (self.rect.width - text_img.get_width()) // 2 y = (self.rect.height - text_img.get_height()) // 2 self.fill(self.background) pygame.draw.ellipse(self, self.foreground, self.get_rect()) self.blit(text_img, (x, y)) return self def connect(self, func): """Set function to call when clicked""" self.callback = func return self def click(self, x, y): """Check if I was clicked. Execute callback method if clicked""" clicked = self.rect.collidepoint(x, y) if clicked and self.callback: self.callback(self) return clicked # Give the buttons something to do def button_pressed(button): label.set_text(label.text + button.text) # Create a label and some buttons label = Label(screen, "", width=20, font=pygame.font.SysFont(None, 36)).at(50, 50) for number in range(9): x = 50 + (number % 3) * 80 y = 260 - (number // 3) * 80 CircleButton(screen, str(number+1), 30, "Blue", "White") \ .connect(button_pressed).at(x, y).draw() CircleButton(screen, "Clear", 55, "Red") \ .connect(lambda x: label.set_text("")).at(300, 100).draw() running = True while running: for event in pygame.event.get(): if event.type == pygame.QUIT: running = False break if event.type == pygame.MOUSEBUTTONUP: CircleButton.clicked(*pygame.mouse.get_pos()) pygame.display.flip() pygame.display.update() pygame.quit()