【问题标题】:Tkinter filedialog breaks entry widgetsTkinter filedialog 打破条目小部件
【发布时间】:2019-06-04 15:33:13
【问题描述】:

tl;dr:当应用程序调用 tkinter.filedialog 时,entry 字段没有正确聚焦。

详细解释:

在初始化 tkinter 应用程序时,entry 字段默认启用。它们的状态是tk.ENABLED,可以通过tab 滚动字段来关注它们,最重要的是,可以单击它们来选择字段。

由于某种原因,调用tkinter.filedialog 会破坏此行为。如果调用tkinter.filedialog的方法,如askdirectoryaskopenfile()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()

这里,如果BR8KFalse,代码行为正确,如果BR8KTrue,代码行为不正确。

(注意:在生产环境中,这将是面向对象的。问题仍然存在于面向对象的环境中。)

【问题讨论】:

  • 如果您在主循环有机会循环至少一次之前启动对话框选项,则 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

标签: python tkinter tk


【解决方案1】:

这是一个已知问题,原因是在第一次到达 mainloop() 之前调用了一个对话窗口。

解决此问题的最简单方法是在对话框前添加update_idletask()

试试这个:

import tkinter as tk
from tkinter import filedialog

BR8K = True

root = tk.Tk()
# By adding this you avoid the focus breaking issue of calling dialog before the mainloop() has had its first loop.
root.update_idletasks() 

if BR8K:
    filedialog.askdirectory()

entry = tk.Entry(root, takefocus=True, highlightthickness=2)
entry.grid(sticky="WE")


root.mainloop()

【讨论】:

  • 这正是问题所在,它也解决了我在生产代码中的问题。谢谢。如果我可能会问,我应该去哪里找到有关该错误的信息?我四处搜寻了一下,在我平常的地方没有找到任何关于此的信息。
  • 如果您不能 100% 确定要搜索什么,有时搜索可能会很困难。因为这样的事情不会产生回溯错误,所以更难。我会说尝试你能想到的最简单的搜索词。比如“文件对话框焦点问题”。
猜你喜欢
  • 1970-01-01
  • 2022-01-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多