我已经设置了一个基本的Pygame图形界面,但我的按钮出现问题。我创建了一个Button
类,按钮执行的函数在__init__()
方法中确定。换句话说,当我通过lambda表达式创建Button
的实例时,我输入了该函数。按钮的相关代码基本上如下所示:
class Button():
def __init__(self, action):
self.command = action
def check(self): # To be called while iterating through pygame.event.get()
if event.type == MOUSEBUTTONUP and self.rect.collidepoint(pygame.mouse.get_pos()):
self.command()
我还创建了一个Window
类,其中每个实例都是一次看到的按钮列表:
class Window():
def __init__(self, buttons):
self.is_visible = False # This determines whether the buttons in this
# window should be updated, checked, and drawn
self.buttons = list(buttons)
def open(self):
self.is_visible = True
def close(self):
self.is_visible = False
def trans(self, new_window):
self.close()
new_window.open()
接下来,我设置了两个Window
个实例,每个实例都有Button
切换回另一个:
WINDOW_1 = Window([Button(lambda: WINDOW_1.trans(WINDOW_2))])
WINDOW_2 = Window([Button(lambda: WINDOW_2.trans(WINDOW_1))])
最后:
WINDOW_1.is_visible = True
问题出现了。
每个按钮的工作方式与它完全相同:它关闭打开的窗口并打开关闭的窗口。不幸的是,如果我在两个按钮重叠的位置点击鼠标(或者如果它们都可见则会重叠的位置),WINDOW_2
按钮的功能会在{{1}的函数后立即调用调用1}}按钮。基本上,WINDOW_1
- > WINDOW_1
- > WINDOW_2
,这一切都发生在同一个循环中
但是,如果我们从WINDOW_1
开始,则会发生这种情况:WINDOW_2
- > WINDOW_2
。看来这个故障只是单向的。我无法弄清楚这里有什么问题,我真的很感激一些帮助。 (以防万一,这里是完整代码的链接,因此您可以重现问题;我已经设置了按钮的位置,以便第一个按钮的下半部分与上半部分重叠第二:http://pastebin.com/m1zCQLRF)。感谢您的阅读,并提前感谢您的回答!
答案 0 :(得分:3)
考虑这些行(来自pastebin):
all_windows=[WINDOW_1,WINDOW_2]
....
for event in pygame.event.get():
for window in all_windows:
if window.is_visible:
for button in window.buttons:
button.update()
button.check()
如果点击WINDOW_1
的按钮,则WINDOW_2.is_visible
变为True
。
在for window in all_windows
循环的下一次迭代中,将调用check
WINDOW_2
方法,因为其is_visible
属性现在为True
。因为这仍然是for event in pygame.event.get()
的相同迭代,WINDOW_2.check()
会看到相同的MOUSEBUTTONUP
事件。 Button对象重叠,因此事件会导致窗口的可见性再次切换,返回到WINDOW_1
可见的状态,这就是绘制的内容。
顺便说一句,使用event.pos
比pygame.mouse.get_pos()
方法中的check()
更准确。前者是事件发布时鼠标的位置,后者是鼠标的当前位置。
我通过一些调整得到了pastebin运行并通过应用快速而肮脏的修复来验证我上面描述的是什么。
首先,我编辑了Button.check()
,因此它返回一个布尔值,显示其检查是否已经过验证:
def check(self):
if event.type==MOUSEBUTTONUP and self.rect.collidepoint(event.pos):
self.command()
return True
return False
如果all_windows
返回check
(即窗口关闭),则更改上面显示的代码以突破True
循环。
for window in all_windows:
if window.is_visible:
for button in window.buttons:
button.update()
_break = button.check()
if _break:
break
现在,当单击按钮时,窗口会按预期关闭并打开。同样,这不是一个“真正的”修复,只是确认导致问题的原因。