问题描述
我正在尝试创建一个GUI,当您单击一个按钮时,该GUI显示一些按钮。但是,我无法弄清楚如何检测是否单击了嵌套按钮。这是我的代码:
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))
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,85))
elif not start_screen and system_screen:
screen.blit(shutdown,85))
pygame.display.flip()
pygame.display.update()
首先,我加载图像,效果很好。接下来,我定义了一个函数 decode ,该函数对我的base 64编码密码进行解码。然后,我定义一个函数 check_mouse_pos ,该函数实际上检查鼠标是否单击了图像。最后,我创建了一个 while 循环,用于检测是否单击了鼠标。
我在Pygame中还很陌生,所以这个问题似乎微不足道:(
解决方法
要回答您的问题,它不起作用,因为一旦start_screen
变为False,函数check_mouse_pos()
就不会起作用。
任何时候您都有诸如按钮之类的东西集合,停下来自己想一想:“我如何用一段代码处理所有这些?”
您的程序具有一组按钮的概念,其中一些按钮显示在系统访问的不同阶段。
因此,您的按钮可能具有一些属性:访问级别,名称,图像,大小,位置。我假设(猜测)随着用户逐步完成各种登录,更多按钮可用。为简单起见,我们将访问权限设为一个整数,其中0
表示“已注销”,然后从该位置开始递增。
这可能导致以下的元组:
logon_butt = ( 0,"Logon","logon_button.png",pygame.Rect( 0,128,128) )
exit_butt = ( 0,"Exit","exit_button.png",pygame.Rect( 160,128) )
door1_butt = ( 1,"Door 1","door.png",160,128) )
door2_butt = ( 1,"Door 2",128) )
...
或课程:
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,( 0,0 ),(128,128) )
exit_butt = Button( 0,( 160,128) )
door1_butt = Button( 1,"Door1",160 ),128) )
door2_butt = Button( 1,"Door2",128) )
...
一旦您有一个元组或类来容纳所有字段,您的代码就可以列出所有按钮:
all_buttons = [ logon_butt,exit_butt,door1_butt,door2_butt ] # etc.
用户输入密码后,存储在user_access_level
中的访问级别数字将增加。因此,他们只能在0
退出或登录。
该列表使您每次单击鼠标事件时都非常容易检查每个按钮:
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?
以上代码使用Button类,但也可以使用butt[0]
这样的元组,而butt[1]
这样的元组等等。
按钮列表还简化了将所有按钮绘制到屏幕的操作:
# 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()
顺便说一句:您只需在主循环中调用一次pygame.display.flip()
(或.update()
)即可。