6

Have a button to open a new window in my code, and have been trying to make the button open a new window called newest_release_window with two things in mind:

  • If newest_release_window is not open, open the window.
  • If newest_release_window is open, set focus on the said window but do not open a new window.

Unfortunately, it has been getting too complicated and I cannot figure out how to do it. The issue is that I cannot make the code detect whether newest_release_window is open or not, and change the variable according to that.

welcome_window = Tk()
welcome_window.title("Games R Us")
welcome_window.geometry("360x350")
welcome_window.configure(bg = "gold")
currentDisplay = 10

newest_release_windowtracker = 0

gui_font_5 = ("Helvetica", 5, "bold")
gui_font_10 = ("Helvetica", 10, "bold")
gui_font_15 = ("Helvetica", 15, "bold")
gui_font_20 = ("Helvetica", 20, "bold")
space_between = (5)
button_variable = IntVar()

def newwindow_newest_release():
    global newest_release_windowtracker
    newest_release_window = Tk()
    newest_release_window.title("Games R Us")

    newest_release_window.geometry("360x350")
    newest_release_window.configure(bg = "greenyellow")
    currentDisplay = 10
    
    display = Label(newest_release_window, text="Humm, see a new window !", 
    bg ="limegreen")
    display.pack()
    
    newest_release_window.withdraw()
    
    if newest_release_windowtracker == 0:
        newest_release_window.deiconify()
        newest_release_windowtracker = 1
    elif newest_release_windowtracker == 1:
        newest_release_window.focus_set()
    elif newest_release_window.winfo_exists == 0:
        newest_release_window = Tk()

ww_newest_release = Button(welcome_window,
            text = "Newest Release", bg = "goldenrod", font = "Helvetica 10", 
            width = 12, command = newwindow_newest_release)

This isn't the full code, I just grabbed the most important parts to give context to what the problem might be.

Michael M.
  • 10,486
  • 9
  • 18
  • 34
  • 1
    I haven't closely examined your code, but I see that you have `newest_release_window = Tk()` in `newwindow_newest_release`. That call doesn't just create the root window, it also creates the Tcl interpreter that performs all of the Tkinter operations, and you really don't want more than one of those. – PM 2Ring May 14 '18 at 12:37
  • 2
    Instead of using `Tk()` to make new windows use `Toplevel()`. `Tk()` should only be used once in tkinter. `Toplevel()` is the correct method for creating new windows after the root window has been made. – Mike - SMT May 14 '18 at 12:58
  • What OS are you using? – Ben the Coder Feb 16 '23 at 15:32
  • I think this will help: https://stackoverflow.com/questions/61482853/in-python-how-to-limit-opening-a-window-or-pushing-a-button-with-tkinter/61483525#61483525?newreg=9fd9b2be65f6443f9d1f7e6560bb5fcb – Леонид Дьячков Aug 18 '23 at 09:44

2 Answers2

0

You can setup a bool defining if the window is opened or not and if it is, then call the lift() method on the instance of tkinter.Tk or tkinter.Toplevel.

Checking if window exists: If there is a root class above the newest_release window, you can check for hasattr(base_class, 'newest_release'). If there is not, then you can setup the window like this global newest_release to be global variable so you can access it outside the function. Then you can create a code like this:

if 'newest_release' in globals():
    newest_release.lift()

or

if hasattr(base_class, 'newest_release'):
    newest_release.lift()
Jakub Bláha
  • 1,491
  • 5
  • 22
  • 43
0

The way I do it is by having one variable to store the Toplevel instance into. I initialize that variable to None first, so I can only set it once (by testing if the variable is None)

The variable is reset back to None when the Toplevel is destroyed (by binding the WM_DELETE_WINDOW protocol).

I also noticed that in your code, you're instanciating a new Tk() object. The Tk() object should only be instanciated once, and be the root of your program. To open new windows, your should use the Toplevel object.

Now for an example :

import tkinter as tk


class OptionsWindow(tk.Frame):
    def __init__(self, master=None, **kwargs):
        super().__init__(master, **kwargs)
        pass


class MainWindow(tk.Frame):
    def __init__(self, master=None, **kwargs):
        super().__init__(master, **kwargs)
        self.options_toplevel = None
        tk.Button(self, text='open toplevel', command=self._open_toplevel).pack()

    def _open_toplevel(self, *args):
        if self.options_toplevel is None:
            self.options_toplevel = tk.Toplevel(self.master)
            self.options_toplevel.protocol('WM_DELETE_WINDOW', self.on_tl_close)
            gui = OptionsWindow(self.options_toplevel, width=300, height=300)
            gui.pack()

    def on_tl_close(self, *args):
        self.options_toplevel.destroy()
        self.options_toplevel = None


root = tk.Tk()
gui = MainWindow(root)
gui.pack()
root.mainloop()
Dogeek
  • 182
  • 9