Python Forum
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Unique Tkinter Window
#11
(Aug-11-2024, 04:41 AM)kucingkembar Wrote: sorry it very basic, i don't understand class,
This is bad. Learn classes, they are very easy to understand. Besides you already use classes in your code, such as Tk, TopLevel, Button. Learn classes from the official Python tutorial.
« We can solve any problem by introducing an extra level of indirection »
Reply
#12
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.
kucingkembar likes this post
Reply


Possibly Related Threads…
Thread Author Replies Views Last Post
  add entries and labels to the window tkinter jacksfrustration 3 2,258 Oct-10-2023, 06:41 PM
Last Post: buran
  Is there a way to call and focus any popup window outside of the main window app? Valjean 6 5,371 Oct-02-2023, 04:11 PM
Last Post: deanhystad
  how to open a popup window in tkinter with entry,label and button lunacy90 1 3,191 Sep-01-2023, 12:07 AM
Last Post: lunacy90
Bug tkinter.TclError: bad window path name "!button" V1ber 2 2,219 Aug-14-2023, 02:46 PM
Last Post: V1ber
  Pyspark Window: perform sum over a window with specific conditions Shena76 0 1,954 Jun-13-2022, 08:59 AM
Last Post: Shena76
  Closing Threads and the chrome window it spawned from Tkinter close button law 0 2,338 Jan-08-2022, 12:13 PM
Last Post: law

Forum Jump:

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020