Comment implémenter les boutons d'option et changer la couleur du bouton dans PyGame?

Nov 29 2020

Veuillez suggérer comment puis-je changer la couleur du bouton lorsque je l'ai appuyé, et la couleur du premier bouton sera changée en couleur par défaut lorsque j'ai appuyé sur le deuxième bouton.

Par exemple, après avoir cliqué sur le bouton DROIT, le bouton deviendra de couleur verte et lorsque je clique sur le bouton GAUCHE, le bouton GAUCHE passera en couleur verte et le bouton DROIT deviendra la couleur par défaut qui est la couleur blanche. Merci d'avance :)

CODE:

def draw_button(self):

    global clicked
    action = False

    # get mouse position
    pos = pygame.mouse.get_pos()

    # create pygame Rect object for the button
    button_rect = Rect(self.x, self.y, self.width, self.height)

    # check mouseover and clicked conditions
    if button_rect.collidepoint(pos):
        if pygame.mouse.get_pressed()[0] == 1:
            clicked = True
            pygame.draw.rect(screen, self.click_col, button_rect)
        elif pygame.mouse.get_pressed()[0] == 0 and clicked == True:
            clicked = False
            action = True
           
        else:
            pygame.draw.rect(screen, self.hover_col, button_rect)
    else:
        pygame.draw.rect(screen, self.button_col, button_rect)

Réponses

1 Rabbid76 Nov 29 2020 at 19:01

Lorsque vous dessinez le bouton, vous devez définir la couleur en fonction de la variable globale clicked:

def draw_button(self):

    global clicked
    
    # get mouse position
    pos = pygame.mouse.get_pos()

    # create pygame Rect object for the button
    button_rect = Rect(self.x, self.y, self.width, self.height)

    # check mouseover and clicked conditions
    hover = button_rect.collidepoint(pos)
    if hover and pygame.mouse.get_pressed()[0] == 1:
        clicked = not clicked

    color = self.button_col
    if clicked:
        color = self.click_col
    elif hover:
        color = self.hover_col

    pygame.draw.rect(screen, color, button_rect)

Quoi qu'il en soit, cela ne vous satisfera pas, car pygame.mouse.get_pressed()renvoie une liste de valeurs booléennes qui représentent l'état ( Trueou False) de tous les boutons de la souris. L'état d'un bouton est Trueaussi long qu'un bouton est maintenu enfoncé.
Vous devez utiliser l' MOUSEBUTTONDOWNévénement. L' MOUSEBUTTONDOWNévénement se produit une fois lorsque vous cliquez sur le bouton de la souris et l' MOUSEBUTTONUPévénement se produit une fois lorsque le bouton de la souris est relâché. L' pygame.event.Event()objet a deux attributs qui fournissent des informations sur l'événement de souris. posest un tuple qui stocke la position sur laquelle l'utilisateur a cliqué. buttonstocke le bouton sur lequel l'utilisateur a cliqué.


Si vous disposez de plusieurs boutons pour interagir les uns avec les autres, un seul clickedstatut ne suffit pas. Vous avez besoin d'un état "cliqué" distinct pour chaque bouton. Si l'état cliqué du bouton 1 devient True, les états des autres clés doivent être définis sur False. Je recommande d'implémenter une RadioButtonclasse pour cela.

Voir aussi Souris et Sprite .

Exemple minimal:

import pygame

class RadioButton(pygame.sprite.Sprite):
    def __init__(self, x, y, w, h, font, text):
        super().__init__() 
        text_surf = font.render(text, True, (0, 0, 0))
        self.button_image = pygame.Surface((w, h))
        self.button_image.fill((96, 96, 96))
        self.button_image.blit(text_surf, text_surf.get_rect(center = (w // 2, h // 2)))
        self.hover_image = pygame.Surface((w, h))
        self.hover_image.fill((96, 96, 96))
        self.hover_image.blit(text_surf, text_surf.get_rect(center = (w // 2, h // 2)))
        pygame.draw.rect(self.hover_image, (96, 196, 96), self.hover_image.get_rect(), 3)
        self.clicked_image = pygame.Surface((w, h))
        self.clicked_image.fill((96, 196, 96))
        self.clicked_image.blit(text_surf, text_surf.get_rect(center = (w // 2, h // 2)))
        self.image = self.button_image
        self.rect = pygame.Rect(x, y, w, h)
        self.clicked = False
        self.buttons = None

    def setRadioButtons(self, buttons):
        self.buttons = buttons

    def update(self, event_list):
        hover = self.rect.collidepoint(pygame.mouse.get_pos())
        for event in event_list:
            if event.type == pygame.MOUSEBUTTONDOWN:
                if hover and event.button == 1:
                    for rb in self.buttons:
                        rb.clicked = False
                    self.clicked = True
        
        self.image = self.button_image
        if self.clicked:
            self.image = self.clicked_image
        elif hover:
            self.image = self.hover_image


pygame.init()
window = pygame.display.set_mode((300, 300))
clock = pygame.time.Clock()
font50 = pygame.font.SysFont(None, 50)

radioButtons = [
    RadioButton(50, 40, 200, 60, font50, "option 1"),
    RadioButton(50, 120, 200, 60, font50, "option 2"),
    RadioButton(50, 200, 200, 60, font50, "option 3")
]
for rb in radioButtons:
    rb.setRadioButtons(radioButtons)
radioButtons[0].clicked = True

group = pygame.sprite.Group(radioButtons)

run = True
while run:
    clock.tick(60)
    event_list = pygame.event.get()
    for event in event_list:
        if event.type == pygame.QUIT:
            run = False 

    group.update(event_list)

    window.fill(0)
    group.draw(window)
    pygame.display.flip()

pygame.quit()
exit()
GameDev Nov 29 2020 at 18:15
your_button_rect = pygame.Rect(x,y,width,height)
color = (0,0,0)
pos = pygame.mouse.get_pos()
def change_button_color():
    if your_button_rect.colliderect(pos):
        if event.type == pygame.MOUSEBUTTONDOWN: #checks if mouse button is pressed down while the cursor is on the rectangle
            color = (your_desired_Color_RGBvalue)

while True:
    pygame.draw.rect(screen,color,your_button_rect)
    change_button_color()