【发布时间】:2014-11-30 13:25:37
【问题描述】:
下面的代码是一个函数的一部分,它产生一个简单的对话框,调用者选择的文本和按钮。
问题在于对“s”、“a”、“d”和“c”的键输入的处理。该代码对于鼠标单击和 Tab 键后跟空格键或 Enter 键操作正确。该代码是用 Python 3.4 编写的,并且正在测试是否符合 Windows 7。
我的理解是 Tk 为最终用户的鼠标点击处理重新聚焦。在用户通过 Tab 键改变焦点后使用空格键和回车键。对于所有这些交互,键都通过代码绑定到每个按钮:
for action in ('<1>', '<space>', '<Return>'):
b.bind(action, handler)
对于“下划线”键输入,我相信我的代码需要在调用处理程序之前处理重新聚焦。这是重新聚焦例程的目的。每当按下 's'、'a'、's' 或 'c' 时,打印语句(“重新聚焦到...”)都会打印正确的 button.winfo_name() 值。这就是我认为button.focus_set() 失败的原因。
如果它有效,这将使处理程序能够通过查看event.widget.winfo_name() 来简单地检查按下了哪个按钮。事实上,重新聚焦失败意味着在event.widget.winfo_name()中使用错误的按钮调用了处理程序
如果我通过制表键手动移动焦点,那么无论按下“s”、“a”、“d”还是“c”中的哪一个,焦点都会给出event.widget.winfo_name() 返回的名称。
在阅读了 Stack Overflow 上的其他帖子后,我尝试在 button.focus_set() 之后添加 button.focus_force()。这对问题没有影响。
我尝试通过将处理程序的签名更改为 def button_handler(event, *args) 然后将 refocus 的最后一行更改为 handler(event, button.winfo_name()) 来传递按钮名称,但 *args 在调用时为空.
def refocus_wrapper(button):
def refocus(event):
print("refocusing to '{}'".format(button.winfo_name()))
button.focus_set()
handler(event)
return refocus
for button_text, underline, button_name in buttons:
b = ttk.Button(button_inner_frame, text=button_text, name=button_name,
underline=underline)
b.pack(padx=2, side='left')
for action in ('<1>', '<space>', '<Return>'):
b.bind(action, handler)
action = '{}'.format(button_text[underline:underline + 1].lower())
dialog.bind(action, refocus_wrapper(b))
if not default or default == button_name:
default = button_name
b.focus_set()
【问题讨论】:
-
在
a、c、d和s键上设置绑定的代码在哪里? -
@BryanOakley。
dialog.bind(action, refocus_wrapper)。最终用户可以看到按钮文本,因此它来自可以轻松国际化的外部配置文件。带下划线的加速键取决于配置文件的语言。例如,由于我不知道梵语中的“取消”是什么样的,也不知道哪个字母将用作加速键,所以下划线也在外部配置文件中。
标签: python python-3.x tkinter tk