【问题标题】:tkinter.simpledialog.Dialog leaves the initiating tkinter.Button depressedtkinter.simpledialog.Dialog 使启动的 tkinter.Button 处于按下状态
【发布时间】:2013-10-12 11:12:40
【问题描述】:

我在 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 是模态的;这可能包括按钮上的&lt;ButtonRelease-1&gt; 鼠标事件?)

问题:

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

【问题讨论】:

    标签: python button dialog tkinter simpledialog


    【解决方案1】:

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

    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 对话:

    【讨论】:

    • 为什么会发生这种情况的第一个问题的答案是,按钮的升起发生在按钮释放时,并且由于代码覆盖了默认行为,因此未处理释放,从而阻止了从处理中释放,直到对话框被解除。正确的解决方案不是在&lt;ButtonRelease&gt; 上添加绑定,而是使用内置的command 属性,它可以正确处理所有绑定和行为。
    【解决方案2】:

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

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

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-08-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多