3

我在 Windows 7 上使用 Python 3.3。我有一个tkinter应用程序可以Button启动tkinter.simpledialog.Dialog. 像这样(这是一个完整的、可运行的示例):

import tkinter
import tkinter.simpledialog

class Mainframe(tkinter.Frame):
    def __init__(self, parent):
        super(Mainframe, self).__init__(parent)
        self.parent = parent
        self.button = tkinter.Button(self, text="Open Dialog")
        open_dialog_op = lambda ev: self.open_dialog(ev)
        self.button.bind("<Button-1>", open_dialog_op)
        self.button.bind("<Return>", open_dialog_op)
        self.button.pack(side=tkinter.LEFT)

    def open_dialog(self, event):
        dialog = tkinter.simpledialog.Dialog(self.parent, "My Dialog")
        self.button.config(relief=tkinter.RAISED)  # does not help!

root = tkinter.Tk()
Mainframe(root).pack()
root.mainloop()

行为:

  • 如果你关注“打开对话框” Button并输入RETURN,一切都很好
  • 如果您用鼠标单击Button,对话框会显示得很好,但是
  • 当对话框关闭时,“打开对话框” Button显示在其郁闷的(tkinter.SUNKEN如果我没记错的话?)状态。
  • (有趣的是,对话框打开时,Button会正常显示。只有在对话框关闭时才会出现沮丧的外观。)
  • 我试图通过简单地调用来修复问题 button.config(relief=tkinter.RAISED),但在这种情况下似乎根本没有做任何事情。

(实际上,我的完整应用程序在单击按钮 后立即开始将按钮显示为按下状态,而不仅仅是在对话框再次关闭时。我发现这更合乎逻辑:simpledialog本地事件循环捕获所有事件,因为它simpledialog 是模态的;这可能包括<ButtonRelease-1>鼠标按钮上的事件?)

问题:

  1. 为什么会这样?
  2. 为什么我的完整应用程序中的行为会有所不同?
  3. 如何避免或修复两者?
4

2 回答 2

3

发生这种情况是因为您部分覆盖了执行正确操作的默认绑定。

如果您希望按钮在按钮激活时执行功能,正确的方法是向command按钮添加选项。我使用“激活”而不是“按下”的原因是——正如你的代码所示——在 tk 中激活按钮的方法不止一种:按下按钮、按下返回、按下加速键等。

您编写的代码不会替换相当大的一组默认绑定。iCodez 的回答确实正确修复了最明显的缺陷,但是让默认绑定保持不变并使用command=将适用于您尚未测试的情况(例如,仅键盘操作)。

于 2013-10-05T14:48:22.547 回答
0

对于第三个问题,我有一个简单的解决方法。实际上,您自己在帖子中已经有了答案。更改此行:

self.button.bind("<Button-1>", open_dialog_op)

对此:

self.button.bind("<ButtonRelease-1>", open_dialog_op)

现在,open_dialog_op鼠标点击是必然的释放。意思是,simpledialog只有在按钮恢复后才会打开(这是它的行为应该是什么)。

不过,我也想提一个建议。为什么不tkinter.messagebox.askokcancel用于这个?与 Windows 的系统提示相同。见下文:

tkinter.simpledialog.Dialog对话:

在此处输入图像描述

tkinter.messagebox.askokcancel对话:

在此处输入图像描述

于 2013-10-05T14:09:27.267 回答