【发布时间】:2019-06-04 15:33:13
【问题描述】:
tl;dr:当应用程序调用 tkinter.filedialog 时,entry 字段没有正确聚焦。
详细解释:
在初始化 tkinter 应用程序时,entry 字段默认启用。它们的状态是tk.ENABLED,可以通过tab 滚动字段来关注它们,最重要的是,可以单击它们来选择字段。
由于某种原因,调用tkinter.filedialog 会破坏此行为。如果调用tkinter.filedialog的方法,如askdirectory或askopenfile(),entry字段仍将保持tk.ENABLED状态,背景将正确设置样式,但点击输入字段不会插入光标或选择字段。当然,打字不会注册。
这可以通过切换到不同的窗口并切换回来来解决。但是,文件对话框窗口(正确地)将用户直接返回到主窗口,因此用户总是看到一个似乎被锁定的主窗口。
看这个例子:
import tkinter as tk
from tkinter import filedialog
BR8K = True
root = tk.Tk()
if BR8K:
filedialog.askdirectory()
entry = tk.Entry(root, takefocus=True, highlightthickness=2)
entry.grid(sticky="WE")
root.mainloop()
这里,如果BR8K 是False,代码行为正确,如果BR8K 是True,代码行为不正确。
(注意:在生产环境中,这将是面向对象的。问题仍然存在于面向对象的环境中。)
【问题讨论】:
-
如果您在主循环有机会循环至少一次之前启动对话框选项,则 tkinter 中的对话框存在一个已知问题,该问题会混淆焦点。您可以使用
after()语句解决此问题,或者使您的对话框成为使用按钮调用的选项。这实际上是 Stack Overflow 上经常提到的一个常见问题。 -
奇怪,我一定没有正确的搜索词。循环部分是有道理的,但您能否简要说明一下
after()将如何在这里使用? -
@
after()是解决此问题的一种方法,方法是设置一个计时器以在 1/10 秒后执行对话框,让主循环有机会到达,但最简单的解决方法是使用update_idletask()直接在对话窗口之前。这是我过去回答过的相关帖子:Tkinter filedialog is stealing focus and not returning it without “Alt-tab” in Python 3.4.1