Pygame:如果还没有检查过,为什么两个按钮都会激活?

时间:2014-10-15 00:08:01

标签: python user-interface python-3.x pygame mouseevent

我已经设置了一个基本的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)。感谢您的阅读,并提前感谢您的回答!

1 个答案:

答案 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.pospygame.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

现在,当单击按钮时,窗口会按预期关闭并打开。同样,这不是一个“真正的”修复,只是确认导致问题的原因。