2017-08-10 1 views
0

Je suis en train d'implémenter un programme qui utilise beaucoup de cadres tkinter et pendant l'ouverture de la sous-trame je veux que la supertrame soit verrouillée pour l'utilisateur (sinon les choses ne fonctionneront pas). Après quelques recherches, j'ai trouvé la méthode grab_set et grab_release qui fonctionnait assez bien.Tkinter Focus perdu après asktring

Cependant, une fois que la sous-trame (instanciée par Toplevel) appelle la demande, la saisie est "perdue" et l'utilisateur peut à nouveau interagir avec la fenêtre de super-niveau. Un exemple serait ce (code très simplifié):

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() 

Une fois que l'utilisateur ouvre la sous-trame en cliquant sur « asdf » le cadre contenant « asdf » sera verrouillé pendant toute la durée alors que le sous-cadre est ouvert. Cependant, une fois que l'utilisateur sélectionne le bouton "demander" dans la sous-trame, ce "verrou" disparaît d'une manière ou d'une autre.

+0

s'il vous plaît fournir un [mcve]. Cela peut également aider à savoir quelle plate-forme vous utilisez. –

+0

Eh bien l'exemple minimal n'est pas si minime ... Je devrais afficher tous les modules et sous-modules pour que ce soit un verificable, puisque le module de super niveau importe divers autres modules que j'ai écrits. – PfannkuchenXD

+0

Je l'ai simplifié autant que j'ai pu et posté le code dans le message original (qui est compilable sur chaque python 3.X). Je travaille sur Windows10. – PfannkuchenXD

Répondre

1

Selon les notes de la bibliothèque tkinter:

Un grab dirige tous les événements à ce sujet et widgets descendant dans l'application.

Je ne suis pas en mesure à ce jour pour trouver toute la documentation qui expliquerait pourquoi le grab_set() est tomber après avoir fini de soumettre votre askstring mais je l'imagerie est, car une fois le widget est allé le grab_set() tombe. Tout comme si vous deviez fermer la fenêtre Toplevel.

Dans ce cas, tl.grab_release() ne semble pas être nécessaire en tant que déclencheurs lorsque la fenêtre se ferme. De ce que j'ai testé si vous avez réinitialisé le grab_set() après le askstring est fait alors il fonctionnera encore correctement. Vous devez simplement ajouter tl.grab_set() juste en dessous de print(tk.simpledialog.askstring("askstring", "askstring")).

Code modifié ci-dessous:

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()