【问题标题】:Depress a button and wait for a second button input = Game move : Issue按下按钮并等待第二个按钮输入=游戏移动:问题
【发布时间】:2016-02-16 18:37:32
【问题描述】:

好的,我的代码有问题,我知道我正在尝试做的动作有效,但我不知道让你在哪种情况下选择哪个动作。

这是我的一个按钮的示例,总共有 25 个

self.B00 = Button(frame)
self.B00.bind("<ButtonRelease-1>", self.clicked)
self.B00.grid(row=0, column=0)
self.B00.config(height=8, width=16)

***** 这是我的按钮单击移动定义 ***** 这是我觉得我遇到问题的地方。您单击 B00 然后应该能够单击 B04 并在 B04 中放置一个 X 并将该行向左移动。发生的事情是,当我单击 B04 时,它正在启动该按钮上的 if 语句,而不是完成原始 if 语句。所以什么也没有发生。我该如何解决这个问题。

def clicked(self, event):
    if event.widget == self.B00:
        print("You can select B04 or B40")
        if event.widget == self.B04:
            self.userMoveLeft(4)
        elif event.widget == self.B40:
            self.userMoveUp(20)

    if event.widget == self.B04:
        if event.widget == self.B00:
            self.userMoveRight(0)
        elif event.widget == self.B44:
            self.userMoveUp(24)

这是我的实际左移定义

def userMoveLeft(self, pos):
    # Is this a valid move?
    if self.board[pos] == " " or self.board[pos] == "X" or self.board[pos] == "O":
        # Record the players move...]
        self.board[pos - 4] = self.board[pos - 3]
        self.board[pos - 3] = self.board[pos - 2]
        self.board[pos - 2] = self.board[pos - 1]
        self.board[pos - 1] = self.board[pos]
        self.board[pos] = "X"
        # Then redraw the board!
        self.redrawBoard()

所以应该发生的是当用户单击按钮 B00 他应该可以选择单击 B04 或 B40,我觉得正在发生的事情是如果您单击 B00 然后单击 B04 它正在停止我的 if 语句并移动到 if 语句在按钮 B04 上并重新开始 if 语句,而不是像应有的那样将 X 放在 B04 上。

如果你玩过,这将是一款 QUIXO 游戏。

我确实知道,如果我在我调用 self.userMoveLeft 或任何移动本身起作用的地方取出 If 语句,那么我的问题在于标有 ***** 的中间定义

我只是想补充一下,我是编程新手,如果我不完全理解,请见谅

我还认为,在用户制作第二个选择棋盘时能够按住按钮会很好。似乎您应该能够将 event.widget == self.B00 设为 Depressed 按钮,直到您选择 self.B04 进行移动,然后 B00 不再被按住。

所有这些都是使用 Python 使用 tkinter 模块完成的

感谢您的帮助。

编辑

我想知道是否有类似的东西 def点击(自我,事件,事件2): 如果 event.widget == self.B00: print("您可以选择 B04 或 B40") 如果 event2.widget == self.B04: self.userMoveLeft(4) elif event2.widget == self.B40: self.userMoveUp(20)

【问题讨论】:

    标签: python button tkinter click self


    【解决方案1】:

    在这段代码中

    def clicked(self, event):
        if event.widget == self.B00:
            print("You can select B04 or B40")
            if event.widget == self.B04:
                self.userMoveLeft(4)
            elif event.widget == self.B40:
                self.userMoveUp(20)
    

    在您执行print 语句后,不会执行任何其他代码。 event.widget 的值为 self.B00,否则我们将不会执行此代码。嵌套的if 语句将不会被执行,因为它们要求event.widget 具有其他值。您显然在想,当用户单击按钮 4 或按钮 40 时,event.widget 的值会发生变化,但事实并非如此。将会发生的情况是,self.click 将被再次调用,其值为 event.widget。

    当您执行像self.click 这样的回调时,它会运行到完成。在完成之前,您无法处理其他事件。所以你对正在发生的事情的心理模型是不正确的。单击按钮 0,self.click 运行。现在,当您按下按钮 4 时,self.click 再次运行。假设 self.click 是一个长时间运行的函数,并且您在第一次调用 self.click 完成运行之前按下了按钮 4。第二次按下按钮将被添加到事件队列中,并且在第一次调用 self.click 完成运行之前不会处理第二次按下按钮。

    也许您想要做的是在按下按钮 0 时禁用除按钮 4 和按钮 40 之外的所有按钮。我不熟悉这个游戏,所以我不知道这是不是一个好主意。

    编辑:要禁用按钮 0,您可以使用

    self.B000.configure(state=tk.DISABLED)
    

    要再次启用它,请使用

    self.B000.configure(state=tk.NORMAL)
    

    我首先会尝试让回调立即禁用所有按钮(编写一个名为disableButtons 或类似的函数),然后只启用您需要的按钮。禁用 40 个按钮应该很快你不会注意到它。当您禁用该按钮时,它将变灰或变暗,以便用户可以清楚地知道他可以按下哪些按钮。

    如果游戏规则适应这种方法,我建议使用dict 显示在特定选择后允许使用哪些按钮。比如

    allowed[self.B000] = [self.B004,self.B040] 
    

    那么你的回调可以开始类似

    def clicked(self, event):
        disableButtons()
        for button in allowed[event.widget]:
            button.configure(state = tk.NORMAL)
    

    【讨论】:

    • 那实际上是完美的,你知道如何禁用除那些按钮之外的所有按钮,正如我所说的我是编程新手,我已经把这些拼凑在一起是自学的,所以我真的很感谢你的帮助.当您禁用所有其他按钮并按 04 或 40 时,它应该在该位置放置一个 X 我可以处理其余的移动列再次感谢您
    • 你不能在同一个回调中有两个事件,正如我上面试图解释的那样。我添加了一些关于启用和禁用小部件的更多细节。在不了解游戏规则的情况下,我无法深入了解它。 (我在网上查了这个游戏,但解释对我来说没有多大意义。)如果这个答案解决了你的问题,请接受它,这样其他人就会知道它已经解决了。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-03-31
    • 2013-08-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-06-22
    相关资源
    最近更新 更多