Python tkinter: Open only one instance at a time of secodary window from primary window
Question:
There are two windows PRIMARY and SECONDARY, I want to open secondary window using a button widget on primary window. But problem is whenever I press that button secondary window is opened, doesn’t matter if a secondary window is already opened or not.
I don’t want this behaviour. I only want to allow only one instance of secondary window at a time.
If a secondary window is already opened, a new secondary window should not be open.
How do I achieve that?
A simple example code is given below to describe the problem more accurately.
from tkinter import *
##############################################################################################
# Function to open secondary window
def fctn_to_open_sec_win():
secondary_window()
# Secondary window
def secondary_window():
window = Tk()
window.title('Secondary window')
window.geometry('300x200')
Label(window, text='nnThis is the secondary window.nn'
'There should be only one instance of it at a time.').pack()
window.mainloop()
# Primary window
def primary_window():
window = Tk()
window.title('Primary window')
window.geometry('400x300')
Button(window, text='Open Secondary window', command=fctn_to_open_sec_win).pack(pady=(30, 0))
window.mainloop()
##############################################################################################
if __name__ == '__main__':
primary_window()
Answers:
You can do it like this,
window_2 = None
def secondary_window():
global window_2
if not window_2:
window_2 = Toplevel()
...
Dont use tk.Tk()
twice in your code, use a tk.Toplevel
instead.
Use a flag to achive this, also you could use the Destroy event of tkinter.
import tkinter as tk
ontop = False
def setflag(event):
global ontop
ontop = False
def top():
global ontop
if not ontop:
top = tk.Toplevel()
top.bind('<Destroy>', setflag)
ontop = True
root = tk.Tk()
b = tk.Button(root,command=top)
b.pack()
root.mainloop()
With classes you could avoid the global statement and even better keepin track of the instances.
similar code and it works the same, choose whichever is easier for you
import tkinter
root = tkinter.Tk()
def open_window():
global win_opened
if not 'win_opened' in globals(): win_opened = False
if win_opened == True: return
window = tkinter.Tk()
win_opened = True
def False_on_close(event): global win_opened ; win_opened = False
window.bind('<Destroy>', False_on_close)
button = tkinter.Button(root,command=open_window).pack()
root.mainloop()
There are two windows PRIMARY and SECONDARY, I want to open secondary window using a button widget on primary window. But problem is whenever I press that button secondary window is opened, doesn’t matter if a secondary window is already opened or not.
I don’t want this behaviour. I only want to allow only one instance of secondary window at a time.
If a secondary window is already opened, a new secondary window should not be open.
How do I achieve that?
A simple example code is given below to describe the problem more accurately.
from tkinter import *
##############################################################################################
# Function to open secondary window
def fctn_to_open_sec_win():
secondary_window()
# Secondary window
def secondary_window():
window = Tk()
window.title('Secondary window')
window.geometry('300x200')
Label(window, text='nnThis is the secondary window.nn'
'There should be only one instance of it at a time.').pack()
window.mainloop()
# Primary window
def primary_window():
window = Tk()
window.title('Primary window')
window.geometry('400x300')
Button(window, text='Open Secondary window', command=fctn_to_open_sec_win).pack(pady=(30, 0))
window.mainloop()
##############################################################################################
if __name__ == '__main__':
primary_window()
You can do it like this,
window_2 = None
def secondary_window():
global window_2
if not window_2:
window_2 = Toplevel()
...
Dont use tk.Tk()
twice in your code, use a tk.Toplevel
instead.
Use a flag to achive this, also you could use the Destroy event of tkinter.
import tkinter as tk
ontop = False
def setflag(event):
global ontop
ontop = False
def top():
global ontop
if not ontop:
top = tk.Toplevel()
top.bind('<Destroy>', setflag)
ontop = True
root = tk.Tk()
b = tk.Button(root,command=top)
b.pack()
root.mainloop()
With classes you could avoid the global statement and even better keepin track of the instances.
similar code and it works the same, choose whichever is easier for you
import tkinter
root = tkinter.Tk()
def open_window():
global win_opened
if not 'win_opened' in globals(): win_opened = False
if win_opened == True: return
window = tkinter.Tk()
win_opened = True
def False_on_close(event): global win_opened ; win_opened = False
window.bind('<Destroy>', False_on_close)
button = tkinter.Button(root,command=open_window).pack()
root.mainloop()