Reputation: 151
I am currently implementing a program that uses many tkinter frames and while subframe is being opened I want the superframe to be locked for the user (otherwise things will not work out). After some research I found the grab_set and grab_release method which worked quite fine.
However once the subframe (instanciated by Toplevel) calls the askstring the grab is "losed" and the user can interact with the superlevel window again. An example would be this (very simplified code):
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()
Once the user opens the subframe by clicking "asdf" the frame containing "asdf" will be locked for the duration while the subframe is opened. However once the user selects the "ask"-Button in the subframe this "lock" somehow disappears.
Upvotes: 0
Views: 1354
Reputation: 364
setting the parent for simpledialog will make simpledialog take focus
x = simpledialog(parent = window_x, title = z etc.)
this will make sure x takes focus and not withdraw
Upvotes: 0
Reputation: 15226
According to the notes in the tkinter library:
A grab directs all events to this and descendant widgets in the application.
I am not able so far to find any documentation that would explain why the grab_set()
is falling off after you finish submitting your askstring
but I would imaging it is because once the widget is gone the grab_set()
falls off. Just like if you were to close out the Toplevel
window.
In this case tl.grab_release()
does not appear to be needed as grab releases once the window closes.
From what I have tested if you reset the grab_set()
after the askstring
is done then it will still work properly.
You need to simply add tl.grab_set()
just below print(tk.simpledialog.askstring("askstring", "askstring"))
.
Modified code below:
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()
Upvotes: 1