Tkinter Focus 在 askstring 后丢失
Tkinter Focus lost after askstring
我目前正在实施一个使用许多 tkinter 框架的程序,并且在打开子框架时我希望为用户锁定超框架(否则事情将无法解决)。经过一些研究,我发现 grab_set 和 grab_release 方法效果很好。
然而,一旦子框架(由 Toplevel 实例化)调用请求字符串,抓取就是 "losed" 并且用户可以再次与超层交互 window。一个例子是这样的(非常简化的代码):
import tkinter as tk
import tkinter.simpledialog
root = tk.Tk()
def open_sublevel():
tl = tk.Toplevel(root)
def ask():
print(tk.simpledialog.askstring("askstring", "askstring"))
tk.Button(tl, text="ask", command=ask).pack()
tl.grab_set()
root.wait_window(tl)
tl.grab_release()
print("release")
tk.Button(root, text="asdf", command=open_sublevel).pack()
tk.mainloop()
一旦用户通过单击 "asdf" 打开子框架,包含 "asdf" 的框架将在子框架打开期间被锁定。然而,一旦用户选择了子框架中的 "ask"-按钮,这个 "lock" 就会以某种方式消失。
根据tkinter库中的注释:
A grab directs all events to this and descendant widgets in the application.
到目前为止,我无法找到任何文档来解释为什么 grab_set()
在您提交完 askstring
后会消失,但我认为这是因为一旦小部件消失了grab_set()
掉下来了。就像您要关闭 Toplevel
window.
在这种情况下,tl.grab_release()
似乎并不需要,因为一旦 window 关闭,抓取就会释放。
根据我的测试,如果您在 askstring
完成后重置 grab_set()
,它仍然可以正常工作。
您只需在 print(tk.simpledialog.askstring("askstring", "askstring"))
下方添加 tl.grab_set()
。
修改后的代码如下:
import tkinter as tk
import tkinter.simpledialog
root = tk.Tk()
def open_sublevel():
tl = tk.Toplevel(root)
tl.grab_set()
def ask():
print(tk.simpledialog.askstring("askstring", "askstring"))
tl.grab_set()
tk.Button(tl, text="ask", command=ask).pack()
print("release")
tk.Button(root, text="asdf", command=open_sublevel).pack()
tk.mainloop()
设置 simpledialog 的父项将使 simpledialog 获得焦点
x = simpledialog(parent = window_x, title = z etc.)
这将确保 x 获得焦点而不是退出
我目前正在实施一个使用许多 tkinter 框架的程序,并且在打开子框架时我希望为用户锁定超框架(否则事情将无法解决)。经过一些研究,我发现 grab_set 和 grab_release 方法效果很好。
然而,一旦子框架(由 Toplevel 实例化)调用请求字符串,抓取就是 "losed" 并且用户可以再次与超层交互 window。一个例子是这样的(非常简化的代码):
import tkinter as tk
import tkinter.simpledialog
root = tk.Tk()
def open_sublevel():
tl = tk.Toplevel(root)
def ask():
print(tk.simpledialog.askstring("askstring", "askstring"))
tk.Button(tl, text="ask", command=ask).pack()
tl.grab_set()
root.wait_window(tl)
tl.grab_release()
print("release")
tk.Button(root, text="asdf", command=open_sublevel).pack()
tk.mainloop()
一旦用户通过单击 "asdf" 打开子框架,包含 "asdf" 的框架将在子框架打开期间被锁定。然而,一旦用户选择了子框架中的 "ask"-按钮,这个 "lock" 就会以某种方式消失。
根据tkinter库中的注释:
A grab directs all events to this and descendant widgets in the application.
到目前为止,我无法找到任何文档来解释为什么 grab_set()
在您提交完 askstring
后会消失,但我认为这是因为一旦小部件消失了grab_set()
掉下来了。就像您要关闭 Toplevel
window.
在这种情况下,tl.grab_release()
似乎并不需要,因为一旦 window 关闭,抓取就会释放。
根据我的测试,如果您在 askstring
完成后重置 grab_set()
,它仍然可以正常工作。
您只需在 print(tk.simpledialog.askstring("askstring", "askstring"))
下方添加 tl.grab_set()
。
修改后的代码如下:
import tkinter as tk
import tkinter.simpledialog
root = tk.Tk()
def open_sublevel():
tl = tk.Toplevel(root)
tl.grab_set()
def ask():
print(tk.simpledialog.askstring("askstring", "askstring"))
tl.grab_set()
tk.Button(tl, text="ask", command=ask).pack()
print("release")
tk.Button(root, text="asdf", command=open_sublevel).pack()
tk.mainloop()
设置 simpledialog 的父项将使 simpledialog 获得焦点
x = simpledialog(parent = window_x, title = z etc.)
这将确保 x 获得焦点而不是退出