ambmil
ambmil

Reputation: 115

Tkinter building windows similar to Root

I am currently working on Tkinter codes. I happen to need to create new windows exactly similar to root but my codes do not perfectly work well. The title does not appear on the new windows. This is an excerpt:

from tkinter import *

#New Window
def New_page():
    window()

#Main Window
def window():

    window = Tk()
    window.resizable(0,0)
    window.configure(background='grey')
    window.state('zoomed')
    window.geometry("2000x4000")

    #Title Frame
    TITLE_FRAME = Frame(window, relief = GROOVE, bg = "black", width=2000, height=160).grid(row=0, column=0, columnspan = 150, rowspan = 30, sticky=E+W)
    Label(TITLE_FRAME, text= 'THIS IS THE TITLE PART', fg='sky blue', bg='black', font='none 40 bold', 
          borderwidth=5).grid(row=0,column=10)

    #New Window Button
    ENTRY_FRAME = Frame(window, bg='sky blue', relief = SUNKEN)
    ENTRY_FRAME.grid(row=40, column=0, columnspan=20, padx=15, pady=15)
    Label(ENTRY_FRAME, text= 'SELECT THE APPROPRIATE DETAILS:',
          bg = 'sky blue', fg='black', font='none 10 bold', borderwidth=5).grid(row=0, column=0, columnspan=20)
    NEW_WINDOW = Button(ENTRY_FRAME, text="NEW WINDOW", font='None 8 bold', width=30, command=New_page, fg= 'black', bg='white')
    NEW_WINDOW.grid(row = 3, column = 0, columnspan = 3, padx = 10, pady = 10)

    window.mainloop()

#Calling the Tkinter function
window()

Upvotes: 1

Views: 315

Answers (1)

Misha Melnyk
Misha Melnyk

Reputation: 409

Like in the comments, Toplevel is the way to go for this one. What I changed:

  1. Moved making the window object globally

  2. Renamed the function to make it makeWindow(master)

  3. makeWindow(master) now takes in a master widget. This will make all of the widgets made there be part of the master window.

  4. New_page was modified to make a new Toplevel() widget

  5. TITLE_FRAME is now made first and then grid is called on it

(EDIT) These edits fix the problems with the original window closing the program.

  1. We want to remap the closing behaviour to act how we want. This is done with window.protocol("WM_DELETE_WINDOW",callback). We must define the callback function, in this case, deleteWindow(win).

  2. What delete window does is take a window, and if it is the root window it hides it. Otherwise, it deletes the window. I used window.withdraw() in my code, but there's probably a better way to do it.

  3. The way it knows if it should close the program is by keeping track of the number of active windows in the activeWindows variable. When a window is created, the number increases, when delete it decreases. If the number of active windows is 0, we can delete the main window to close the program cleanly.

  4. The way we bind the deleteWindow(win) callback is through an anonymous function. Normally, the protocol mentioned above does not give any arguments, but we want to know which window called the function. To do this, whenever we bind the destruction of the window, we define a anonymous function using lambda that calls deleteWindow.

.

from tkinter import *

window = Tk()
window.resizable(0,0)
window.configure(background='grey')
window.state('zoomed')
window.geometry("2000x4000")
activeWindows = 1

def deleteWindow(win):
    if win == window:
        window.withdraw()
    else:
        win.destroy()

    global activeWindows
    activeWindows-=1
    if activeWindows <= 0:
        window.destroy()

#New Window
def New_page():
    global activeWindows
    activeWindows+=1
    NEW_WINDOW=Toplevel(background='grey')
    NEW_WINDOW.geometry("2000x4000")
    NEW_WINDOW.protocol("WM_DELETE_WINDOW",lambda:deleteWindow(NEW_WINDOW))
    makeWindow(NEW_WINDOW)

#Main Window
def makeWindow(master):
    #Title Frame
    TITLE_FRAME = Frame(master, relief = GROOVE, bg = "black", width=2000, height=160)
    TITLE_FRAME.grid(row=0, column=0, columnspan = 150, rowspan = 30, sticky=E+W)
    Label(TITLE_FRAME, text= 'THIS IS THE TITLE PART', fg='sky blue', bg='black', font='none 40 bold', 
          borderwidth=5).grid(row=0,column=10)

    #New Window Button
    ENTRY_FRAME = Frame(master, bg='sky blue', relief = SUNKEN)
    ENTRY_FRAME.grid(row=40, column=0, columnspan=20, padx=15, pady=15)
    Label(ENTRY_FRAME, text= 'SELECT THE APPROPRIATE DETAILS:',
          bg = 'sky blue', fg='black', font='none 10 bold', borderwidth=5).grid(row=0, column=0, columnspan=20)
    NEW_WINDOW = Button(ENTRY_FRAME, text="NEW WINDOW", font='None 8 bold', width=30, command=New_page, fg= 'black', bg='white')
    NEW_WINDOW.grid(row = 3, column = 0, columnspan = 3, padx = 10, pady = 10)

window.protocol("WM_DELETE_WINDOW",lambda: deleteWindow(window))

#Calling the Tkinter function
makeWindow(window)
window.mainloop()

Upvotes: 3

Related Questions