Reputation: 69
I bound the opening of a new window (Tk.Toplevel) on a button. However, if I press the button twice, two windows turn on. Can I deactivate the button until the new window is turned off, or display a message box if I press the button twice ?
Upvotes: 1
Views: 1254
Reputation: 142641
You can disable/enable
button or you can assign TopLevel
to global variable which at start has value None
and you check if it is still None
before creating window. if it is not None
then don't create window. When you close window then you set it again None
.
This method can be use for any object which can be only one at some moment - ie. bullet in game.
import tkinter as tk # PEP8: `import *` is not preferred
# --- functions ---
def close_top():
global single_top
single_top.destroy()
single_top = None
def open_top():
global single_top
if single_top is None:
single_top = tk.Toplevel(root)
l = tk.Label(single_top, text='TopLevel')
l.pack()
single_top.protocol("WM_DELETE_WINDOW", close_top)
else:
print("Top level already exists")
# --- main ---
single_top = None
root = tk.Tk()
b = tk.Button(root, text='TOP', command=open_top)
b.pack()
root.mainloop()
EDIT:
The same structure with disabled button
import tkinter as tk # PEP8: `import *` is not preferred
# --- functions ---
def close_top():
single_top.destroy()
b['state'] = 'normal'
def open_top():
global single_top
b['state'] = 'disable'
single_top = tk.Toplevel(root)
l = tk.Label(single_top, text='TopLevel')
l.pack()
single_top.protocol("WM_DELETE_WINDOW", close_top)
# --- main ---
root = tk.Tk()
b = tk.Button(root, text='TOP', command=open_top)
b.pack()
root.mainloop()
Upvotes: 2
Reputation: 3275
If you don't want to import an external library. You can simply check if root contains any instance of Toplevel
using isinstance()
.
Here is an example:
from tkinter import *
from tkinter import messagebox
def top():
if not any(isinstance(x, Toplevel) for x in root.winfo_children()):
top = Toplevel(root)
lbl = Label(top, text='TopLevel')
lbl.pack()
else:
messagebox.showinfo("showinfo", "Top level already exists")
root = Tk()
btn = Button(root, text='text', command=top)
btn.pack()
root.mainloop()
If you simply want to disable the button.
from tkinter import *
from tkinter import messagebox
def top():
btn['state'] = 'disabled'
top = Toplevel(root)
lbl = Label(top, text='TopLevel')
lbl.pack()
top.protocol("WM_DELETE_WINDOW", lambda : btn.configure(state='normal') or top.destroy())
root = Tk()
btn = Button(root, text='text', command=top)
btn.pack()
root.mainloop()
Upvotes: 6