grab_set() function not working in tkinter

Viewed 937

I have asked a question previously about the same, here is a link to that: "Blink" Prompt window if parent window is clicked Tkinter

But it was marked as duplicate. Please help me with my code as I am not able to implement grab_set() in my code even after repeated tries. I was advised to open a new question, so here it is.

My Code:

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

Even after putting grab_set() on the pr window , I can access the root window. Please tell the correct way to put this function inside my code.

2 Answers

Your code has some problems like pointed in previous answer (use Toplevel instead of Tk for the second window and use mainloop only once) and a few other mores that you should avoid, like importing tkinter twice, creating the root window inside a function in a local variable, or doing b1 = Button(..).grid(...), when the grid() method doesn't return anything so b1 = None. Beside that, for an exit application prompt, I think you will prefer to use grab_set_global(), but as I told you before, you have to be careful with grab since tkinter can only grab a window that has been mapped on the screen, thus you need to use wait_visibility() before. Here is an improvement of your code:

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

The problem is that you're creating two root windows (ie: two instances of Tk). These instances are separate environments, so any widget in one can't affect or talk to a widget in another.

For a grab to work, all windows need to be under the same root. Your prompt function needs to create an instance of Toplevel rather than Tk. Also, you should not call mainloop more than once.

Related