Home > Back-end >  Buttons keep appearing and reappearing
Buttons keep appearing and reappearing

Time:10-20

I ran into a problem where I added two buttons to the window but they would constantly appear and reappear on the window. I don't think they are a loop of any kind, but I might be completely wrong on this part. The buttons do stay still whenever the webcam is off but will start disappearing and reappearing again once the webcam is on. I'm looking for a way to make the button stay still on the window and the webcam active at the same time. Note that I'm using the cv2 library to display my webcam on the window.

Here is my code:

import pygame 
import cv2
#import numpy as np

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))
    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 
    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()

CodePudding user response:

It is a matter of Indentation. buttons.update() and buttons.draw(WINDOW) must be called in the application loop not in the event loop:

def draw_window():
    # background color 
    WINDOW.fill((color))
    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 
    for event in pygame.event.get():
        # [...]
                

    # INDENTATION
    #<--|
    buttons.update()
    buttons.draw(WINDOW)
    
    # update the display
    pygame.display.update()
  • Related