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()
Asked By: Ecto Ruseff

||

Answers:

You can do it like this,

window_2 = None

def secondary_window():
    global window_2
    if not window_2:
        window_2 = Toplevel()
        ...
Answered By: Jason Yang

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.

Answered By: Thingamabobs

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()
Answered By: hastoy
Categories: questions Tags: , , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.