La función grab_set () no funciona en tkinter

Nov 11 2020

Anteriormente hice una pregunta sobre el mismo, aquí hay un enlace a eso: "Parpadeo" Ventana de solicitud si se hace clic en la ventana principal

Pero estaba marcado como duplicado. Ayúdame con mi código, ya que no puedo implementar grab_set () en mi código incluso después de varios intentos. Se me aconsejó que abriera una nueva pregunta, así que aquí está.

Mi código:

import tkinter
from tkinter import *

def mainwindow():
  root = Tk()
  root.geometry("100x100")

  b1 = Button(root, text="Exit", command=prompt)
  b1.place(x=50, y=40)
  mainloop()

def prompt():
  pr = Tk()
  pr.geometry("175x100")
  pr.grab_set()

  lable = Label(pr, text="Do you want to exit?").grid(row=0, column=0, padx=20, pady=15)
  b1 = Button(pr, text="Yes", command=exit).grid(row=1, column=0, padx=75)
  mainloop()

mainwindow()

Incluso después de colocar grab_set()la prventana, puedo acceder a la rootventana. Indique la forma correcta de poner esta función dentro de mi código.

Respuestas

FlavioMoraes Nov 12 2020 at 04:00

Su código tiene algunos problemas como se señaló en la respuesta anterior (use en Toplevellugar de Tkpara la segunda ventana y use mainloopsolo una vez) y algunas otras costumbres que debe evitar, como importar tkinter dos veces, crear la ventana raíz dentro de una función en una variable local, o haciendo b1 = Button(..).grid(...), cuando el grid()método no devuelve nada b1 = None. Además de eso, para un mensaje de salida de la aplicación, creo que preferirá usar grab_set_global(), pero como le dije antes, debe tener cuidado con la captura, ya que tkinter solo puede tomar una ventana que se ha asignado en la pantalla, por lo que debe usar wait_visibility()antes. Aquí hay una mejora de su código:

from tkinter import *

def mainwindow():
    root.geometry("100x100")

    b1 = Button(root, text="Exit", command=prompt)
    b1.place(x=50, y=40)

def prompt():
    pr = Toplevel()
    pr.geometry("175x100")
    pr.wait_visibility()
    pr.grab_set_global()

    label = Label(pr, text="Do you want to exit?").grid(row=0, column=0, padx=20, pady=15)
    Button(pr, text="Yes", command=exit).grid(row=1, column=0, padx=75)

root = Tk()   
mainwindow()
root.mainloop()
BryanOakley Nov 12 2020 at 03:42

El problema es que está creando dos ventanas raíz (es decir, dos instancias de Tk). Estas instancias son entornos separados, por lo que cualquier widget en uno no puede afectar o comunicarse con un widget en otro.

Para que un agarre funcione, todas las ventanas deben estar bajo la misma raíz. Tu promptfunción necesita crear una instancia de en Toplevellugar de Tk. Además, no debe llamar mainloopmás de una vez.