Python Forum
[PyGame] inset countdown in panel
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
[PyGame] inset countdown in panel
#7
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()
Reply


Messages In This Thread
inset countdown in panel - by Frankduc - May-03-2022, 06:26 PM
RE: inset countdown in panel - by deanhystad - May-03-2022, 08:05 PM
RE: inset countdown in panel - by Frankduc - May-03-2022, 08:25 PM
RE: inset countdown in panel - by deanhystad - May-03-2022, 08:40 PM
RE: inset countdown in panel - by Frankduc - May-03-2022, 09:25 PM
RE: inset countdown in panel - by deanhystad - May-03-2022, 10:18 PM
RE: inset countdown in panel - by deanhystad - May-05-2022, 09:26 PM

Forum Jump:

User Panel Messages

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