With the following code you will be able to open a new window from the root window. We’ve done it yet into a post of some days ago, but in that code you could open the same window as many times as you wanted. What if you do want to prevent the chance for the user to open it more times, but just create it once? I thought to this solutions that uses the state() method of Tk(), to check if the window is open. If it is, it will return you ‘normal’ as state. I put the code into a try except:
if the window does not exist => the error will raise an exception (NameError)
if the window state is normal => it focus on the window, not creating another window
Code with Class
In this first example we are going to use a class Win2 to build a very basic window, that is called by the function new_window triggered by the click of the button.
import tkinter as tk def new_window(Win_class): global win2 try: if win2.state() == "normal": win2.focus() except NameError as e: print(e) win2 = tk.Toplevel(win) Win_class(win2) class Win2: def __init__(self, root): self.root = root self.root.geometry("300x300+500+200") self.root["bg"] = "navy" win = tk.Tk() win.geometry("200x200+200+100") button = tk.Button(win, text="Open new Window") button['command'] = lambda: new_window(Win2) button.pack() text = tk.Text(win, bg='cyan') text.pack() win.mainloop()
A different version without Class, with a function
If you need something very simple and no more than one type of windows, you can also use this very simple code:
import tkinter as tk def new_window1(): " new window" try: if win1.state() == "normal": win1.focus() except NameError as e: print(e) win1 = tk.Toplevel() win1.geometry("300x300+500+200") win1["bg"] = "navy" lb = tk.Label(win1, text="Hello") lb.pack() win = tk.Tk() win.geometry("200x200+200+100") button = tk.Button(win, text="Open new Window") button['command'] = new_window1 button.pack() win.mainloop()
Video about making one window from the another only once
Tkinter test for students
Tkinter articles
Other suggested post about tkinter:
- The azure theme
Open a new window once with he Azure dark theme
import tkinter as tk from tkinter import ttk class App(ttk.Frame): def __init__(self, parent): ttk.Frame.__init__(self) self.win2_status = 0 # to open the new window once self.setup_frames() self.setup_button() def setup_frames(self): # frame for button --------------- frame 0 / button self.button_frame0 = ttk.LabelFrame(self, text="Azure dark Theme App", padding=(20, 10)) self.button_frame0.grid( row=0, column=0, padx=(20, 10), pady=(20, 10), sticky="nsew") def setup_button(self): self.accentbutton = ttk.Button( self.button_frame0, text="CLick to open new window", style="Accent.TButton", command=lambda: self.new_window(Win2) ) self.accentbutton.grid(row=7, column=0, padx=5, pady=10, sticky="nsew") def new_window(self,winclass): if self.win2_status == 0: try: if self.win2.status == 'normal': # if it's not created yet self.win2.focus_force() except: self.win2 = tk.Toplevel(root) # create Win2(self.win2) # populate self.win2_status = 1 class Win2: def __init__(self, _root): self.root = _root self.root.geometry("300x300+500+200") self.root["bg"] = "navy" self.root.protocol("WM_DELETE_WINDOW", self.close) def close(self): print("Window destroyed") app.win2_status = 0 self.root.destroy() if __name__ == "__main__": root = tk.Tk() root.title("Azure dark theme") # Simply set the theme root.tk.call("source", "azure.tcl") root.tk.call("set_theme", "dark") app = App(root) app.pack(fill="both", expand=True) # Set a minsize for the window, and place it in the middle root.update() root.minsize(root.winfo_width(), root.winfo_height()) x_cordinate = int((root.winfo_screenwidth() / 2) - (root.winfo_width() / 2)) y_cordinate = int((root.winfo_screenheight() / 2) - (root.winfo_height() / 2)) root.geometry("+{}+{}".format(x_cordinate, y_cordinate-20)) root.mainloop()
Here is the output
Subscribe to the newsletter for updates
Tkinter templates
My youtube channel
Twitter: @pythonprogrammi - python_pygame