This is your code modified to only have one newwindow.
import tkinter as tk
newwindow = None
def openwindow():
global newwindow
if newwindow is None:
newwindow = tk.Toplevel()
newwindow.minsize(400, 200)
newwindow.title("new window")
newwindow.protocol("WM_DELETE_WINDOW", newwindow.withdraw)
newentry = tk.Entry(newwindow)
newentry.pack()
newentry.insert(tk.END, f"edit here")
else:
newwindow.deiconify()
root = tk.Tk()
root.title("root")
root.minsize(400, 200)
button = tk.Button(root, text='Create new window')
button['command'] = openwindow
button.pack()
root.mainloop()
The main change is using a global variable to keep track of the window. Only create the window once. After window is created, use deiconify to show the window. Set the window delete protocol to hide the window instead of deleting.
The code is ugly. The code depends on a global variable being defined before the function is called making it difficult to use. Here I repackage the same code using a class.
import tkinter as tk
class NewWindow(tk.Toplevel):
"""A toplevel window with an Entry"""
def __init__(self):
"""Initialize window."""
super().__init__()
self.minsize(400, 200)
self.title("new window")
self.protocol("WM_DELETE_WINDOW", self.withdraw)
self.text = tk.StringVar(self, "edit here")
tk.Entry(self, textvariable=self.text).pack()
class MainWindow(tk.Tk):
"""Main window for application."""
def __init__(self):
super().__init__()
self.title("Main Window")
self.minsize(400, 200)
self.newwindow = None
tk.Button(self, text='Create new window', command=self.new_window).pack()
def new_window(self):
if self.newwindow is None:
self.newwindow = NewWindow()
else:
self.newwindow.deiconify()
MainWindow().mainloop()
If you really want there to only be one NewWindow, the class can be rewritten to use a singleton pattern.
import tkinter as tk
class NewWindow(tk.Toplevel):
"""A toplevel window singleton (is unique.)"""
_shared_window = None
def __new__(cls):
"""Called when NewWindow() is used in your code."""
if cls._shared_window is None:
# Only make new window once. Return new window
return super().__new__(cls)
# Return existing window
return cls._shared_window
def __init__(self):
"""Initialize window. Automatically called after __new__()."""
if self._shared_window is None:
# Only initialize window once.
super().__init__()
self.minsize(400, 200)
self.title("new window")
self.protocol("WM_DELETE_WINDOW", self.withdraw)
self.text = tk.StringVar(self, "edit here")
tk.Entry(self, textvariable=self.text).pack()
# Set _shared_window so we don't do this again
NewWindow._shared_window = self
else:
# Draw existing window.
self._shared_window.deiconify()
class MainWindow(tk.Tk):
"""Main window for application."""
def __init__(self):
super().__init__()
self.title("Main Window")
self.minsize(400, 200)
tk.Button(self, text='Create new window', command=self.new_window).pack()
def new_window(self):
window = NewWindow()
print(window)
MainWindow().mainloop()
I don't see any reason for a class like this, but I include for completeness. I think it is better design if the user of NewWindow only creates one instance and uses it over and over instead of making a class that forces singleton behavior.
Gribouillis is right about classes. Everything you use in Python is a class. If you don't understand classes enough to write one, then you probably don't understand enough to use them effectively.