0

I ran into the problem of the button's functionality being delayed when clicked or doesn't work at all. I believe that it is still in a loop of some kind but I couldn't find anything wrong with it unless it has something to do with the webcam being on and the webcam interfering with the button being clicked each time.

import pygame 
import cv2

pygame.init()

# setting the width and height of the window
WIDTH, HEIGHT = 1280, 720
WINDOW = pygame.display.set_mode((WIDTH, HEIGHT))
pygame.display.set_caption("PANIC")

# background color 
color = ("black")

# Webcam 
camera = cv2.VideoCapture(0) # 0 is the built in webcam
camera.set(cv2.CAP_PROP_FRAME_WIDTH, 1200) # frame width 
camera.set(cv2.CAP_PROP_FRAME_HEIGHT, 1000) # frame height 

# function that will display (draw) stuff 
def draw_window():
    # background color 
    WINDOW.fill((color))
    
    # displaying the webcam 
    success, image = camera.read()
    if success:
        camera_surf = pygame.image.frombuffer(image.tobytes(), image.shape[1::-1], "BGR")
        WINDOW.blit(camera_surf, (0,0))
    
    # Buttons function
    for event in pygame.event.get():
        if event.type == pygame.MOUSEMOTION:
            # 2. put the collide check for mouse hover here for each button
            if b0.rect.collidepoint(pygame.mouse.get_pos()):
                b0.colors = "red on green"
            elif b1.rect.collidepoint(pygame.mouse.get_pos()):
                b1.colors = "red on green"
            else:
                # this will work for every buttons going back to original color after mouse goes out
                not_hover()
        if event.type == pygame.MOUSEBUTTONDOWN:
            # 3. here the interactions with the click of the mouse... done
            if b0.rect.collidepoint(pygame.mouse.get_pos()):
                print("ON") # print text of button 1
            if b1.rect.collidepoint(pygame.mouse.get_pos()):
                print("OFF") # prints text of button 2 
                
    buttons.update()
    
    buttons.draw(WINDOW)
    
    # update the display
    pygame.display.update()

FPS = 30
def mainWindow():
    # keeping the window open 
    run = True 
    clock = pygame.time.Clock()
    while run: 
        # capping it at the set frame rate 
        clock.tick(FPS)
        
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                run = False
                        
        draw_window()
        pygame.display.update()
        
    # closing the window 
    pygame.quit()
    
              
              
def not_hover():
    for x in buttons:
        x.colors = "red on yellow"
        x.update()

# button class 
buttons = pygame.sprite.Group()
class Button(pygame.sprite.Sprite):
    def __init__(self, WINDOW, position, text, size, colors="white on blue"):
        super().__init__()
        self.colors = colors
        self.fg, self.bg = self.colors.split(" on ")
        self.font = pygame.font.SysFont("Arial", size)
        self.text_render = self.font.render(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.update()
        buttons.add(self)

    def update(self):
        self.fg, self.bg = self.colors.split(" on ")
        pygame.draw.line(WINDOW, (150, 150, 150), (self.x, self.y), (self.x + self.w , self.y), 5)
        pygame.draw.line(WINDOW, (150, 150, 150), (self.x, self.y - 2), (self.x, self.y + self.h), 5)
        pygame.draw.line(WINDOW, (50, 50, 50), (self.x, self.y + self.h), (self.x + self.w , self.y + self.h), 5)
        pygame.draw.line(WINDOW, (50, 50, 50), (self.x + self.w , self.y + self.h), [self.x + self.w , self.y], 5)
        pygame.draw.rect(WINDOW, self.bg, (self.x, self.y, self.w , self.h))

b0 = Button(WINDOW, (800, 10), "SWITCH ON", 55, "red on yellow")
b1 = Button(WINDOW, (800, 100), "SWITCH OFF", 55, "red on yellow")


# main #
mainWindow()
Saltbottle
  • 43
  • 3
  • Do not call `pygame.event.get()` multiple times per frame. Get the list of event in the application loop `event_list = pygame.event.get()`. Use that list in the `for`-loops (pass it to `draw_window`). See the example in [Faster version of 'pygame.event.get()'. Why are events being missed and why are the events delayed?](https://stackoverflow.com/questions/58086113/faster-version-of-pygame-event-get-why-are-events-being-missed-and-why-are/58087070#58087070) – Rabbid76 Oct 19 '22 at 16:25

0 Answers0