Tkinter按钮在按下后不会改变其释放度

问题描述:

为什么我按下tkinter Button后,其按钮仍处于凹陷"状态?

Why does my tkinter Button stays in the "sunken" relief after I press it?

import tkinter
from tkinter import messagebox as msgbox 

class GUI(object):
    def __init__(self):
        self.root = tkinter.Tk()
        self.root.geometry("200x200")
        self.root.title("Test")


        self.testButton = tkinter.Button(self.root, text="Click Me!")
        self.testButton.bind("<Button-1>", self.click)
        self.testButton.bind("<ButtonRelease-1>", self.release)
        self.testButton.pack()

    def release(self, event):
        event.widget.config(relief=tkinter.RAISED)

    def click(self, event):
        result =  msgbox.askokcancel("Continue?", "Do you want to continue?")
        if result:
            print("Okay")
        else:
            print("Well then . . .")
        print(event.widget.cget("relief"))
        print()

if __name__ == "__main__":
    test = GUI()
    test.root.mainloop()

控制台显示浮雕是凸起的",但在GUI上却是凹入的"浮雕,为什么?按下按钮后的GUI

The console shows that the relief is "raised" but on the GUI it stays in the "sunken" relief , why? The GUI after pressing the Button

您的回调正在打印凸起",因为您的代码在默认按钮绑定之前运行,因此实际上在您函数被调用.

Your callback is printing "raised" because your code is run before the default button bindings, so the button relief is in fact raised at the point in time when your function is called.

我很确定这是导致按钮沉没的原因:

I'm pretty sure this is what is causing the button to stay sunken:

  1. 您单击按钮,然后出现一个对话框.由于tkinter的默认绑定还没有运行 1 的机会,所以默认情况下,该按钮被抬起,并且是默认绑定导致按钮看上去凹陷了
  2. 将出现一个对话框,该对话框从主窗口窃取焦点.
  3. 您单击并释放按钮以单击对话框.由于对话框夺走了焦点,因此第二个释放事件不会传递给按钮
  4. 这时,原始点击的处理继续进行,控制权变为按钮点击的默认tkinter绑定.
  5. 默认行为会导致按钮下陷
  6. 这时,您的鼠标按钮未被按下,因此自然无法释放该按钮.因为您无法释放按钮,所以窗口永远不会看到释放事件.
  7. 由于该按钮从未看到按钮释放事件,因此该按钮保持凹陷状态
  1. you click on the button, and a dialog appears. At this point the button is raised because tkinter's default binding has not yet had a chance to run 1, and it is the default bindings which cause the button to appear sunken
  2. a dialog appears, which steals the focus from the main window.
  3. you click and release the button to click on the dialog. Because the dialog has stolen the focus, this second release event is not passed to the button
  4. at this point the processing of the original click continues, with control going to the default tkinter binding for a button click.
  5. the default behavior causes the button to become sunken
  6. at this point, your mouse button is not pressed down, so naturally you can't release the button. Because you can't release the button, the window never sees a release event.
  7. Because the button never sees a button release event, the button stays sunken

1 有关tkinter如何处理事件的说明,请参见以下答案: https://*.com/a/11542200/7432 .答案集中在键盘事件上,但是相同的机制适用于鼠标按钮.

1 For a description of how tkinter handles events, see this answer: https://*.com/a/11542200/7432. The answer is focused on keyboard events, but the same mechanism applies to mouse buttons.