gpt4 book ai didi

python - tkinter .focus_set() 失败

转载 作者:太空宇宙 更新时间:2023-11-03 18:03:52 24 4
gpt4 key购买 nike

下面的代码是一个函数的一部分,该函数生成一个简单的对话框,其中包含调用者选择的文本和按钮。

Dialog with example text and four buttons: Save, save As, Don't save, Cancel

问题在于对“s”、“a”、“d”和“c”键输入的处理。对于鼠标单击和 Tab 键后跟空格键或 Enter 键,代码可以正确运行。该代码是用 Python 3.4 编写的,并且正在测试是否符合 Windows 7。

我的理解是 Tk 处理最终用户鼠标点击的重新聚焦。在用户通过 Tab 键切换焦点后使用空格键和 Enter 键。对于所有这些交互,按键都通过代码绑定(bind)到每个按钮:

for action in ('<1>', '<space>', '<Return>'):
b.bind(action, handler)

对于“下划线”键输入,我相信我的代码需要在调用处理程序之前处理重新聚焦。这就是重新聚焦例程的目的。每当按下 's'、'a'、's' 或 'c' 时,打印语句(“refocussing to...”)就会打印出正确的 button.winfo_name() 值。这就是为什么我认为 button.focus_set() 失败了。

如果它有效,这将使处理程序能够通过查看 event.widget.winfo_name() 来简单地检查按下了哪个按钮。事实上,重新聚焦失败意味着使用 event.widget.winfo_name() 中的错误按钮调用处理程序

如果我通过 Tab 键手动移动焦点,则无论按下“s”、“a”、“d”或“c”中的哪一个,焦点都会给出 event.widget.winfo_name() 返回的名称。

阅读完 Stack Overflow 上的其他帖子后,我尝试在 button.focus_force() 之后添加 button.focus_set() 。这对问题没有影响。

我尝试通过将处理程序的签名更改为 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()

最佳答案

您最初关于需要将焦点设置在按钮上的假设是不正确的。在 Tk 中处理此问题的常用方法是在对话框顶层表单上绑定(bind)加速键事件,并调用事件绑定(bind)的按钮调用方法。

在 Tcl/Tk 中:

toplevel .dlg
pack [button .dlg.b -text "Save" -underline 0 -command {puts "Save pressed"}]
bind .dlg <Alt-s> {.dlg.b invoke}

因此,将按键事件绑定(bind)到作为按钮父级的顶层。如果这是一个对话框,那么它的父级应该是应用程序顶级小部件。

Python 的等价物是:

from tkinter import *
main = Tk()
dialog = Toplevel(main)
button = Button(dialog, text="Send", underline="0", command=lambda: print("hello"))
button.pack()
dialog.bind('<Alt-s>', lambda event: button.invoke())
main.mainloop()

按键绑定(bind)将一个事件对象附加到回调函数,我们可以使用 lambda 来丢弃该事件对象,以包装按钮的调用方法的调用。

关于python - tkinter .focus_set() 失败,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27213711/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com