Python Forum
Thread Rating:
  • 1 Vote(s) - 1 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Buttons in PyGame
#1
Hi guys,

I'm doing my A Level computing project currently. Although I am aware it is more difficult to create a GUI on PyGame compared to, for instance, PyQT, I decided I was going to use PyGame for the entire project anyway - this is because my project is for young children, so the menu needs to be bright, colourful, and easy for them to understand, which I don't believe PyQT can do.

I was wondering, how do you label buttons in PyGame? I've been able to make a button, but I can't get the text to go in the middle - is there a way to do this? Also, since I will need to make a lot of buttons, I tried to make a button class, but honestly, that's just confused me too. I also attempted to make a function to initialise the text coming from what's in the class, but I'm not sure how to get it to work without me specifying which button I want (which would defeat the point of me making a function). This part might not make sense, but hopefully the code will at least make a bit more sense as to what I'm trying to do?

As a somewhat new programmer (I've done Python for a few years, but I haven't attempted big projects like this), all the examples I've looked at to try and understand have just been confusing.

Please can someone explain to me, very simply, how to go about making the GUI? This is my code so far - it's not great, and a lot of it is just testing, but it's just so you can have a basic idea of where I'm up to haha.

Thanks!
import pygame
import os

pygame.init()
screen = pygame.display.set_mode((600, 400))
done = False
clock = pygame.time.Clock()

WHITE = (255, 255, 255)
RED = (255, 0, 0)

buttonText = pygame.font.SysFont('Comic Sans MS', 20)

class Button:
    def __init__ (self, colour, x, y, width, height, label):
        self.colour = colour
        self.x = x
        self.y = y
        self.width = width
        self.height = height
        self.label = label

    def getColour(self):
        return(self.colour)

    def getX(self):
        return(self.x)

    def getY(self):
        return(self.y)

    def getWidth(self):
        return(self.getWidth)

    def getHeight(self):
        return(self.getHeight)

    def getLabel(self):
        return(self.getHeight)

teacher = Button([255, 0, 0], 450, 100, 100, 50, "Teacher")
student = Button([255, 0, 0], 450, 200, 100, 50, "Student")

def initialiseText(buttonText, i):
    text = i.getLabel()
    textSurface = buttonText.render(text)

while done == False:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            done = True

    screen.fill(WHITE)  

    #teacher = pygame.draw.rect(screen, teacher.getColour, [teacher.getX, teacher.getY, teacher.getWidth, teacher.getHeight])
    teacher = pygame.draw.rect(screen, RED, [200, 200, 100, 100]) 
    initialiseText(buttonText, teacher)
    screen.blit(textSurface, teacher.center)
    
    if event.type == pygame.MOUSEBUTTONDOWN:
        mouse = pygame.mouse.get_pos()
        if button.collidepoint(mouse):
            print("hi")
Reply
#2
Your button class is quite weak as it just attempt to recreate pygame built in rect class. You might as well just utilize pygame.rect to handling positioning of an object and it's drawing position. Dont even bother using pygame.draw.rect.

(Oct-03-2018, 12:45 PM)mzmingle Wrote: I was wondering, how do you label buttons in PyGame? I've been able to make a button, but I can't get the text to go in the middle - is there a way to do this? Also, since I will need to make a lot of buttons, I tried to make a button class, but honestly, that's just confused me too.


This is basically the button class i use. At this point just keep using that same class over and over because its so flexible and has decent button features in consideration. And i change it if needed. I would look through the classes and identify what is going on exactly to understand how to change it if you need to. process_kwargs() is setting default settings and allowing a dict of different values to be set as the instance variables. render_text() is setting up the color of the text based on if its being hovered over. check_event() is checking if the button is being pressed or not. on_click()/on_release() is an extension of check_event() but checking for mouse collision and determining if the button is pressed when the button is pressed or released, etc. check_hover() is checking if the mouse is hovering over hte button rect. update() is the meat of the button that runs every frame....it does the action of everything else. It defines the text color based on hover or being clicked, and positions the text in the center of the button's rect. It also draws the button itself and inflates it by 4 pixels.
https://github.com/Mekire/pygame-button

The last 3 lines of the class are where it puts the text in the center of the button.
Quote:
        if self.text:
            text_rect = text.get_rect(center=self.rect.center)
            surface.blit(text,text_rect)

self.rect is the button's rectangle rect and it places that center to the text.rect's center and then renders it there.

tl;dr
If you have a rectangle rect and a text rect, all you have to do is basically
text.rect.center = button.rect.center
where you assign the button's center to the texts center. Then you just draw the text to it's own rect's position.
Recommended Tutorials:
Reply
#3
Thank you! To be honest, I just don't understand classes very well - will research that though lmao!
Reply
#4
you basically just want to put the data and logic for the button into the class. This will clean up the code to get rid of button data and logic elsewhere as well as make it modular to use for numerous buttons.

As you can see in the link i showed, in the example, he just created a button object and input the default values in and centered that specific button where he wanted it
        self.button = Button((0,0,200,50),RED, self.change_color,
                             text=message, **BUTTON_STYLE)
self.button.rect.center = (self.screen_rect.centerx,100)
From there you just have to run that class event and update methods in the proper spot. There is no change to that code unless you have numerous buttons, in which it would just loop a list of buttons to update their event and update methods. You can just keep reusing the same class, but send in different values for different buttons. That is the main feature of classes.
Recommended Tutorials:
Reply
#5
Oof. I'm still using user defined basic color constants there. Nasty.
Reply


Possibly Related Threads…
Thread Author Replies Views Last Post
  [PyGame] pygame-manu : using controller buttons to move around menu mlw19mlw91 2 1,607 Mar-12-2023, 01:55 PM
Last Post: deanhystad
  Pygame - Images As Buttons vman44 3 12,964 Mar-20-2020, 08:13 PM
Last Post: vman44
  [pygame] Equiping inventory slots with invisible buttons SheeppOSU 6 4,720 Apr-26-2019, 08:45 PM
Last Post: SheeppOSU
  Problems with loading buttons (pygame) SheeppOSU 2 3,095 Apr-12-2019, 08:04 PM
Last Post: SheeppOSU
  Menus, buttons and other widgets for Pygame Olleus 4 11,471 Apr-17-2017, 11:08 PM
Last Post: metulburr

Forum Jump:

User Panel Messages

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