Create more windows with tkinter

One thing that I think could be useful is to create more windows using tkinter for a program to make it easy to manage different things to do, without having to put too many stuffs in the same window. So here is the final code, after the image of the windows generated in the example:

First you create the main window

import tkinter as tk

class Win1:
	def __init__(self, master):
		self.master = master
		self.master.geometry("400x400")
		self.frame = tk.Frame(self.master)
		self.butnew("Click to open Window 2", "2", Win2)
		self.butnew("Click to open Window 3", "3", Win3)
		self.frame.pack()

	def butnew(self, text, number, _class):
		tk.Button(self.frame, text = text, command= lambda: self.new_window(number, _class)).pack()

	def new_window(self, number, _class):
		self.new = tk.Toplevel(self.master)
		_class(self.new, number)

There is a way to open different windows through buttons writing less code:

  • butnew to create a button that opens a new window calling new_window function
  • new_window is called clicking the button

For every new window you need to create a new class (passed as argument in butnew function) like this:

class Win2:
	def __init__(self, master, number):
		self.master = master
		self.master.geometry("400x400+200+200")
		self.frame = tk.Frame(self.master)
		self.quit = tk.Button(self.frame, text = f"Quit this window n. {number}", command = self.close_window)
		self.quit.pack()
		self.frame.pack()

	def close_window(self):
		self.master.destroy()

Why not to create another window, being so easy?

class Win3:
	def __init__(self, master, number):
		self.master = master
		self.master.geometry("400x400+200+200")
		self.frame = tk.Frame(self.master)
		self.quit = tk.Button(self.frame, text = f"Quit this window n. {number}", command = self.close_window)
		self.quit.pack()
		self.label = tk.Label(self.frame, text="THIS IS ONLY IN THE THIRD WINDOW")
		self.label.pack()
		self.frame.pack()

	def close_window(self):
		self.master.destroy()

And you can go on this way further writing all the windows you need.

at the end you create an istance of the first window in this loop:

root = tk.Tk()
app = Win1(root)
root.mainloop()

You will find the code below, after this image, and the video with the live coding too.

import tkinter as tk

class Win1:
	def __init__(self, master):
		self.master = master
		self.master.geometry("400x400")
		self.frame = tk.Frame(self.master)
		self.butnew("Click to open Window 2", "2", Win2)
		self.butnew("Click to open Window 3", "3", Win3)
		self.frame.pack()

	def butnew(self, text, number, _class):
		tk.Button(self.frame, text = text, command= lambda: self.new_window(number, _class)).pack()

	def new_window(self, number, _class):
		self.new = tk.Toplevel(self.master)
		_class(self.new, number)

class Win2:
	def __init__(self, master, number):
		self.master = master
		self.master.geometry("400x400+200+200")
		self.frame = tk.Frame(self.master)
		self.quit = tk.Button(self.frame, text = f"Quit this window n. {number}", command = self.close_window)
		self.quit.pack()
		self.frame.pack()

	def close_window(self):
		self.master.destroy()

class Win3:
	def __init__(self, master, number):
		self.master = master
		self.master.geometry("400x400+200+200")
		self.frame = tk.Frame(self.master)
		self.quit = tk.Button(self.frame, text = f"Quit this window n. {number}", command = self.close_window)
		self.quit.pack()
		self.label = tk.Label(self.frame, text="THIS IS ONLY IN THE THIRD WINDOW")
		self.label.pack()
		self.frame.pack()


	def close_window(self):
		self.master.destroy()

root = tk.Tk()
app = Win1(root)
root.mainloop()

Video: making multiple windows with Python and tkinter

P.S.: in the video there is a little mistake; the label in the third window must be attached to self.frame and not to master. So I changed in the code above:

self.label = tk.Label(master, text=”THIS IS ONLY IN THE THIRD WINDOW”)

with

self.label = tk.Label(self.frame, text=”THIS IS ONLY IN THE THIRD WINDOW”)

Some restyling of the code

import tkinter as tk


class Win1:
    def __init__(self, master):
        self.master = master
        self.master.geometry("400x300")
        self.show_widgets()

    def show_widgets(self):
        self.frame = tk.Frame(self.master)
        self.master.title("Window n.1")
        self.create_button("Click to open Window 2", Win2)
        self.create_button("Click to open Window 3", Win3)
        self.frame.pack()

    def create_button(self, text, _class):
        "Button that creates a new window"
        tk.Button(
            self.frame, text=text,
            command=lambda: self.new_window(_class)).pack()

    def new_window(self, _class):
        self.win = tk.Toplevel(self.master)
        _class(self.win)


class Win2(Win1):
    def __init__(self, master):
        self.master = master
        self.master.title("Window n.2")
        self.master.geometry("400x100+200+200")
        self.show_widgets()

    def show_widgets(self):
        "A frame with a button to quit the window"
        self.frame = tk.Frame(self.master, bg="red")
        self.quit_button = tk.Button(
            self.frame, text=f"Quit this window n. 2",
            command=self.close_window)
        self.quit_button.pack()
        self.create_button("Open window 3 from window 2", Win3)
        self.frame.pack()

    def close_window(self):
        self.master.destroy()


class Win3(Win1):
    def __init__(self, master):
        self.master = master
        self.master.title("Window n.3")
        self.master.geometry("400x200+200+200")
        self.show_widgets()

    def show_widgets(self):
        self.frame = tk.Frame(self.master, bg="green")
        self.quit = tk.Button(
            self.frame, text=f"Quit this window n. 3",
            command=self.close_window)
        self.quit.pack()
        self.label = tk.Label(
            self.frame, text="THIS IS ONLY IN THE THIRD WINDOW")
        self.label.pack()
        self.frame.pack()

    def close_window(self):
        self.master.destroy()


root = tk.Tk()
app = Win1(root)
root.mainloop()

Optimizing code

Since we do not need some stuff inherited by the main class, we will have this code:

import tkinter as tk


class Win1:
    def __init__(self, master):
        self.master = master
        self.master.geometry("400x300")
        self.show_widgets()

    def show_widgets(self):
        self.frame = tk.Frame(self.master)
        self.master.title("Window n.1")
        self.create_button("Click to open Window 2", Win2)
        self.create_button("Click to open Window 3", Win3)
        self.frame.pack()

    def create_button(self, text, _class):
        "Button that creates a new window"
        tk.Button(
            self.frame, text=text,
            command=lambda: self.new_window(_class)).pack()

    def new_window(self, _class):
        self.win = tk.Toplevel(self.master)
        _class(self.win)

    def close_window(self):
        self.master.destroy()

class Win2(Win1):

    def show_widgets(self):
        "A frame with a button to quit the window"
        self.frame = tk.Frame(self.master, bg="red")
        self.quit_button = tk.Button(
            self.frame, text=f"Quit this window n. 2",
            command=self.close_window)
        self.quit_button.pack()
        self.create_button("Open window 3 from window 2", Win3)
        self.frame.pack()



class Win3(Win2):

    def show_widgets(self):
        self.frame = tk.Frame(self.master, bg="green")
        self.quit_button = tk.Button(
            self.frame, text=f"Quit this window n. 3",
            command=self.close_window)
        self.label = tk.Label(
            self.frame, text="THIS IS ONLY IN THE THIRD WINDOW")
        self.label.pack()
        self.frame.pack()



root = tk.Tk()
app = Win1(root)
root.mainloop()

Now you can open the windows only once (specific) at the time

import tkinter as tk


class Win1:
    def __init__(self, master):
        self.master = master
        self.master.geometry("400x300")
        self.show_widgets()

    def show_widgets(self):
        self.frame = tk.Frame(self.master)
        self.master.title("Window n.1")
        self.create_button("Click to open Window 2", Win2)
        self.create_button("Click to open Window 3", Win3)
        self.frame.pack()

    def create_button(self, text, _class):
        "Button that creates a new window"
        tk.Button(
            self.frame, text=text,
            command=lambda: self.new_window(_class)).pack()

    def new_window(self, _class):
            global win2, win3

            try:
                if _class == Win2:
                    if win2.state() == "normal":
                        win2.focus()
            except:  
                win2 = tk.Toplevel(self.master)
                _class(win2)

            try:
                if _class == Win3:
                    if win3.state() == "normal":
                        win3.focus()
            except:  
                win3 = tk.Toplevel(self.master)
                _class(win3)

    def close_window(self):
        self.master.destroy()

class Win2(Win1):

    def show_widgets(self):
        "A frame with a button to quit the window"
        self.master.title("Window 2")
        self.frame = tk.Frame(self.master, bg="red")
        self.quit_button = tk.Button(
            self.frame, text=f"Quit this window n. 2",
            command=self.close_window)
        self.quit_button.pack()
        self.create_button("Open window 3 from window 2", Win3)
        self.frame.pack()



class Win3(Win2):

    def show_widgets(self):
        self.master.title("Window 3")
        self.frame = tk.Frame(self.master, bg="green")
        self.quit_button = tk.Button(
            self.frame, text=f"Quit this window n. 3",
            command=self.close_window)
        self.label = tk.Label(
            self.frame, text="THIS IS ONLY IN THE THIRD WINDOW")
        self.label.pack()
        self.frame.pack()



root = tk.Tk()
app = Win1(root)
root.mainloop()

This is it


Subscribe to the newsletter for updates
Tkinter templates
Avatar My youtube channel

Twitter: @pythonprogrammi - python_pygame

Videos

Speech recognition game

Pygame's Platform Game

Other Pygame's posts

Published by pythonprogramming

Started with basic on the spectrum, loved javascript in the 90ies and python in the 2000, now I am back with python, still making some javascript stuff when needed.