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