[英]How to detect mouse clicks inside nested buttons in pygame
I'm trying to create a GUI that displays some buttons when you click a button.我正在尝试创建一个 GUI,当您单击按钮时会显示一些按钮。 However, I cannot figure out how to detect if you click the nested button.但是,我无法弄清楚如何检测您是否单击了嵌套按钮。 Here's my code:这是我的代码:
import pygame
from pygame.locals import *
import sys
import os
import time
from random import randrange, randint
import base64
from configparser import ConfigParser
import tkinter
from tkinter import Tk, messagebox, simpledialog
configure = ConfigParser()
configure.read('dooroperatingsystempassword.txt')
start_time = time.time()
WIDTH = 801
HEIGHT = 452
CENTER_X = WIDTH / 2
CENTER_Y = HEIGHT / 2
admin = False
complete = False
failed = False
loading = False
first_time_password = True
back_button_dofalsetotrue = 'none'
back_button_dotruetofalse = 'none'
start_screen = True
system_screen = False
privacy_screen = False
account_screen = False
time_button_screen = False
keyboard_screen = False
shutdown_screen = False
system = pygame.image.load(r'images\system_button.png')
privacy = pygame.image.load(r'images\security_button.png')
background = pygame.image.load(r'images\background.png')
shutdown = pygame.image.load(r'images\shutdown.png')
doors_icon = pygame.image.load(r'images\doors2_icon.png')
pygame.init()
clock = pygame.time.Clock()
screen = pygame.display.set_mode((WIDTH, HEIGHT))
pygame.mouse.set_visible(1)
pygame.display.set_caption('Doors Operating System (DOS)')
pygame.display.set_icon(doors_icon)
root = Tk()
root.withdraw()
shutdown_img_for_tkinter = tkinter.PhotoImage(file=r'images\shutdown.png')
root.iconphoto(False, shutdown_img_for_tkinter)
def letters_off():
global loading
if loading:
loading = False
def decode(decode_message):
base64_bytes = decode_message.encode('ascii').decode('UTF-8')
message = base64.b64decode(base64_bytes).decode('UTF-8')
return message
def check_mouse_pos(pos):
global start_screen, loading_first_time_password
global system_screen, privacy_screen, account_screen, time_button_screen, keyboard_screen, shutdown_screen
print(pos)
if start_screen and pos[0] >= 145 and pos[0] <= 233 and pos[1] >= 85 and pos[1] <= 167:
password2 = simpledialog.askstring('Welcome to Systems', 'Password?')
paswrd2 = configure.get('password section 2', 'password2')
paswrd2 = paswrd2.rstrip()
paswrd2 = decode(paswrd2)
if password2 == paswrd2:
start_screen = False
system_screen = True
print('sfdfsfsdfsfsdfsf')
#while not start_screen and system_screen:
# if pos[0] >= 315 and pos[0] <= 403 and pos[1] >= 85 and pos[1] <= 167:
# print('es')
while not failed:
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
sys.exit()
elif event.type == pygame.MOUSEBUTTONDOWN:
position = pygame.mouse.get_pos()
if start_screen:
check_mouse_pos(position)
screen.blit(background, (0, 0))
if first_time_password:
screen.blit(background, (0, 0))
pygame.display.update()
password1 = simpledialog.askstring('Welcome to Doors Operating System', 'Password?')
paswrd1 = configure.get('password section 1', 'password1')
paswrd1 = paswrd1.rstrip()
paswrd1 = decode(paswrd1)
if password1 == paswrd1:
print('yay dun')
first_time_password = False
if not complete:
if start_screen and not system_screen:
screen.blit(system, (145, 85))
elif not start_screen and system_screen:
screen.blit(shutdown, (315, 85))
else:
messagebox.showinfo('Error 001', 'LOL NOOB YOU FAILED ROFL LOL NOOB HAHA LOOK AT YOUR FACE IT LOOKS LIKE DEATH ROFL LOL')
pygame.quit()
sys.exit()
else:
if not complete:
if start_screen and not system_screen:
screen.blit(system, (145, 85))
elif not start_screen and system_screen:
screen.blit(shutdown, (315, 85))
pygame.display.flip()
pygame.display.update()
First, I load my images, which work fine.首先,我加载我的图像,它工作正常。 Next, I defined a function decode that decodes my base 64 encoded passwords.接下来,我定义了一个函数decode来解码我的 base 64 编码密码。 Then, I define a function check_mouse_pos that actually checks if the mouse has clicked on the image.然后,我定义了一个函数check_mouse_pos来实际检查鼠标是否点击了图像。 Finally, I made a while loop that detects if I clicked my mouse.最后,我做了一个while循环来检测我是否点击了我的鼠标。
I'm pretty new in Pygame, so this question my seem trivial :(我是 Pygame 的新手,所以这个问题我觉得微不足道:(
To answer your question, it's not working because once start_screen
becomes False, the function check_mouse_pos()
doesn't do much.要回答您的问题,它不起作用,因为一旦start_screen
变为 False,函数check_mouse_pos()
就不会做太多事情。
Anytime you have a collection of things, like buttons, pause and think to yourself: "How can I handle all of these with one section of code?"任何时候你有一堆东西,比如按钮,停下来思考一下:“我如何用一段代码处理所有这些?”
Your program has the concept of a set of buttons, some of which are shown at different phases of the system access.您的程序具有一组按钮的概念,其中一些按钮显示在系统访问的不同阶段。
So probably your button has some attributes: Access-Level, Name, Image, Size, Location.所以可能你的按钮有一些属性:访问级别、名称、图像、大小、位置。 I'm assuming (guessing) that as the user progresses through the various logons, more buttons become available.我假设(猜测)随着用户进行各种登录,更多的按钮变得可用。 To keep it simple, let's make the access an integer, with 0
meaning "logged out", and increasing from there.为了简单起见,让我们将访问设置为整数, 0
表示“已注销”,并从那里增加。
This leads to perhaps tuples of:这可能导致以下元组:
logon_butt = ( 0, "Logon", "logon_button.png", pygame.Rect( 0,0, 128,128) )
exit_butt = ( 0, "Exit", "exit_button.png", pygame.Rect( 160,0, 128,128) )
door1_butt = ( 1, "Door 1", "door.png", pygame.Rect( 0,160, 128,128) )
door2_butt = ( 1, "Door 2", "door.png", pygame.Rect( 160,160, 128,128) )
...
Or a class:或者一个类:
class Button:
def __init__( self, access, name, image_filename, location, size )
self.access = access
self.name = name
self.image = pygame.image.load( image_filename )
self.image = pygame.transform.smoothscale( image, size )
self.rect = self.image.get_rect()
self.rect.x = location[0]
self.rect.y = location[1]
logon_butt = Button( 0, "Logon", "logon_button.png", ( 0,0 ), (128,128) )
exit_butt = Button( 0, "Exit", "exit_button.png", ( 160,0 ), (128,128) )
door1_butt = Button( 1, "Door1", "door.png", ( 0,160 ), (128,128) )
door2_butt = Button( 1, "Door2", "door.png", ( 160,160 ), (128,128) )
...
Once you have a tuple or class to hold all the fields, your code can make a list of all buttons:一旦你有一个元组或类来保存所有的字段,你的代码就可以列出所有按钮:
all_buttons = [ logon_butt, exit_butt, door1_butt, door2_butt ] # etc.
When the user completes a password, the access-level number stored in user_access_level
increases.当用户完成密码时, user_access_level
存储的访问级别编号user_access_level
增加。 So at 0
they can only exit or login.所以在0
他们只能退出或登录。
The list makes it very easy to check every button each time you get a mouse-click event:每次获得鼠标单击事件时,该列表都可以很容易地检查每个按钮:
while not failed:
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
sys.exit()
elif event.type == pygame.MOUSEBUTTONDOWN:
position = pygame.mouse.get_pos()
# check which button was pressed
for butt in all_buttons:
if ( butt.rect.collidepoint( position ) ): # click inside button
print( "Button [" + butt.name +"] pressed" )
if ( butt.access <= user_access_level ): # is user allowed?
print( "User access OK" )
else:
print( "No ACCESS" )
# TODO - another login level?
The above code uses the Button class, but alternatively it could have used the tuple like butt[0]
for access, and butt[1]
for name, etc.上面的代码使用 Button 类,但也可以使用像butt[0]
这样的元组进行访问,使用butt[1]
表示名称等。
The button list also simplifies drawing all the buttons to the screen:按钮列表还简化了将所有按钮绘制到屏幕的过程:
# repaint screen
screen.blit( background, (0, 0) )
# draw any buttons the user has access to
for butt in all_buttons:
if ( butt.access <= user_access_level ):
screen.blit( butt.image, butt.rect )
pygame.display.flip()
BTW: you only need to call pygame.display.flip()
(or .update()
) once in the main loop.顺便说一句:您只需要在主循环中调用pygame.display.flip()
(或.update()
)一次。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.