Python new window tkinter

Create a New Window in Tk (tkinter)

Desktop applications can be made up of more than one window. The main window is created by the tk.Tk class and controls the life cycle of the application. Secondary windows, also known as popup or child windows, might be created on application startup or in response to an event (for example, a button press) via the tk.Toplevel class. When the user closes the main window, secondary windows are also closed, thus ending the program execution. However, child windows can be opened and closed multiple times during the application life cycle.

The following code creates an application with a parent window and a child window. The main window contains a button that opens the secondary window. Inside the secondary window there is another button to close itself.

import tkinter as tk
from tkinter import ttk
def open_secondary_window ():
# Create secondary (or popup) window.
secondary_window = tk . Toplevel ()
secondary_window . title ( «Secondary Window» )
secondary_window . config ( width = 300 , height = 200 )
# Create a button to close (destroy) this window.
button_close = ttk . Button (
secondary_window ,
text = «Close window» ,
command = secondary_window . destroy
)
button_close . place ( x = 75 , y = 75 )
# Create the main window.
main_window = tk . Tk ()
main_window . config ( width = 400 , height = 300 )
main_window . title ( «Main Window» )
# Create a button inside the main window that
# invokes the open_secondary_window() function
# when pressed.
button_open = ttk . Button (
main_window ,
text = «Open secondary window» ,
command = open_secondary_window
)
button_open . place ( x = 100 , y = 100 )
main_window . mainloop ()
Читайте также:  Php get env file

Having two different windows, whenever we create a widget (be it a button or any other), we must specify its parent window (i.e., the window in which it is located) as the first argument. The button_open is inside the main window, hence in line 27 the main_window object is passed as the first argument. The same goes for the button_close and the secondary window on line 12. Here is the result:

In order for the child window to get focus automatically once created, we use the focus() method:

def open_secondary_window ():
# Create secondary (or popup) window.
secondary_window = tk . Toplevel ()
secondary_window . title ( «Secondary Window» )
secondary_window . config ( width = 300 , height = 200 )
# Create a button to close (destroy) this window.
button_close = ttk . Button (
secondary_window ,
text = «Close window» ,
command = secondary_window . destroy
)
button_close . place ( x = 75 , y = 75 )
secondary_window . focus ()

When the two windows are open, the user will be able to interact with both of them. If we want the user to be unable to use the main window while the secondary window is visible (known in the GUI jargon as modal window), we call the grab_set() method:

def open_secondary_window ():
# Create secondary (or popup) window.
secondary_window = tk . Toplevel ()
secondary_window . title ( «Secondary Window» )
secondary_window . config ( width = 300 , height = 200 )
# Create a button to close (destroy) this window.
button_close = ttk . Button (
secondary_window ,
text = «Close window» ,
command = secondary_window . destroy
)
button_close . place ( x = 75 , y = 75 )
secondary_window . focus ()
secondary_window . grab_set () # Modal.

Both the main window and the child window provide the destroy() method to close them programmatically. Note that main_window.destroy() finishes the whole application.

Читайте также:  Underline fonts in html

Although this way of organizing the code can be useful for small applications, a better solution is to create a class for each window. So the code above in its object-oriented version would look something like this:

import tkinter as tk
from tkinter import ttk
class SecondaryWindow ( tk . Toplevel ):
def __init__ ( self , * args , ** kwargs ):
super () . __init__ ( * args , ** kwargs )
self . config ( width = 300 , height = 200 )
self . title ( «Secondary Window» )
self . button_close = ttk . Button (
self ,
text = «Close window» ,
command = self . destroy
)
self . button_close . place ( x = 75 , y = 75 )
self . focus ()
self . grab_set ()
class MainWindow ( tk . Tk ):
def __init__ ( self , * args , ** kwargs ):
super () . __init__ ( * args , ** kwargs )
self . config ( width = 400 , height = 300 )
self . title ( «Main Window» )
self . button_open = ttk . Button (
self ,
text = «Open secondary window» ,
command = self . open_secondary_window
)
self . button_open . place ( x = 100 , y = 100 )
def open_secondary_window ( self ):
self . secondary_window = SecondaryWindow ()
main_window = MainWindow ()
main_window . mainloop ()

This implementation has the benefit that widgets and methods of both windows are encapsulated within their respective objects ( main_window and secondary_window ), avoiding name collisions and reducing usage of global objects. The classes could even be in different modules: it’s a common pattern in GUI development to put each window in its own source code file.

Other features are also easier to implement with this arrangement of windows into classes. For example, what happens if the user presses the button_open more than once? If the child window is not modal (i.e., grab_set() has not been called), the user will be allowed to open an arbitrary amount of child windows. This is generally an undesirable effect, so it is useful to add a constraint so that the SecondaryWindow does not get open more than once at the same time.

import tkinter as tk
from tkinter import ttk
class SecondaryWindow ( tk . Toplevel ):
# Class attribute that indicates whether this child window
# is being used (alive) or not.
alive = False
def __init__ ( self , * args , ** kwargs ):
super () . __init__ ( * args , ** kwargs )
self . config ( width = 300 , height = 200 )
self . title ( «Secondary Window» )
self . button_close = ttk . Button (
self ,
text = «Close window» ,
command = self . destroy
)
self . button_close . place ( x = 75 , y = 75 )
self . focus ()
# Set the window as alive once created.
self . __class__ . alive = True
def destroy ( self ):
# Restore the attribute on close.
self . __class__ . alive = False
return super () . destroy ()
class MainWindow ( tk . Tk ):
def __init__ ( self , * args , ** kwargs ):
super () . __init__ ( * args , ** kwargs )
self . config ( width = 400 , height = 300 )
self . title ( «Main Window» )
self . button_open = ttk . Button (
self ,
text = «Open secondary window» ,
command = self . open_secondary_window
)
self . button_open . place ( x = 100 , y = 100 )
def open_secondary_window ( self ):
if not SecondaryWindow . alive :
self . secondary_window = SecondaryWindow ()
main_window = MainWindow ()
main_window . mainloop ()

The logic under this code is simple. We create the alive attribute that is true when the window is in use and false otherwise, and always query it before instantiating the child window.

But what if we want to access an object within a child window from the parent window? For example, if we want to create a child window for the user to enter his name and then display it in a label in the parent window:

An elegant solution for this scenario is to use a callback function (heavily used in event-driven programming), which will be called by the child window when the entered name is available. This approach is similar to that used in buttons when passing a function name to the command argument.

import tkinter as tk
from tkinter import ttk
class InputWindow ( tk . Toplevel ):
def __init__ ( self , * args , callback = None , ** kwargs ):
super () . __init__ ( * args , ** kwargs )
# callback is a function that this window will call
# with the entered name as an argument once the button
# has been pressed.
self . callback = callback
self . config ( width = 300 , height = 90 )
# Disable the button for resizing the window.
self . resizable ( 0 , 0 )
self . title ( «Enter Your Name» )
self . entry_name = ttk . Entry ( self )
self . entry_name . place ( x = 20 , y = 20 , width = 260 )
self . button_done = ttk . Button (
self ,
text = «Done!» ,
command = self . button_done_pressed
)
self . button_done . place ( x = 20 , y = 50 , width = 260 )
self . focus ()
self . grab_set ()
def button_done_pressed ( self ):
# Get the entered name and invoke the callback function
# passed when creating this window.
self . callback ( self . entry_name . get ())
# Close the window.
self . destroy ()
class MainWindow ( tk . Tk ):
def __init__ ( self , * args , ** kwargs ):
super () . __init__ ( * args , ** kwargs )
self . config ( width = 400 , height = 300 )
self . title ( «Main Window» )
self . button_request_name = ttk . Button (
self ,
text = «Request name» ,
command = self . request_name
)
self . button_request_name . place ( x = 50 , y = 50 )
self . label_name = ttk . Label (
self ,
text = «You have not entered your name yet.»
)
self . label_name . place ( x = 50 , y = 150 )
def request_name ( self ):
# Create the child window and pass the callback
# function by which we want to receive the entered
# name.
self . ventana_nombre = InputWindow (
callback = self . name_entered
)
def name_entered ( self , name ):
# This function is invoked once the user presses the
# «Done!» button within the secondary window. The entered
# name will be in the «name» argument.
self . label_name . config (
text = «Your name is: » + name
)
main_window = MainWindow ()
main_window . mainloop ()

Источник

Create a New Window by Clicking a Button in Tkinter

Create a New Window by Clicking a Button in Tkinter

In this tutorial, we will show you how to create and open a new Tkinter window by clicking a button in Tkinter.

Create a New Tkinter Window

import tkinter as tk  def createNewWindow():  newWindow = tk.Toplevel(app)  app = tk.Tk() buttonExample = tk.Button(app,  text="Create new window",  command=createNewWindow) buttonExample.pack()  app.mainloop() 

We normally use tk.Tk() to create a new Tkinter window, but it is not valid if we have already created a root window as shown in the above codes.

Toplevel is the right widget in this circumstance as the Toplevel widget is intended to display extra pop-up windows.

buttonExample = tk.Button(app,  text="Create new window",  command=createNewWindow) 

It binds the createNewWindow function to the button.

The new window is an empty window in the above example and you could add more widgets to it just like adding widgets in a normal root window, but need to change the parent widget to the created Toplevel window.

import tkinter as tk  def createNewWindow():  newWindow = tk.Toplevel(app)  labelExample = tk.Label(newWindow, text = "New Window")  buttonExample = tk.Button(newWindow, text = "New Window button")   labelExample.pack()  buttonExample.pack()  app = tk.Tk() buttonExample = tk.Button(app,  text="Create new window",  command=createNewWindow) buttonExample.pack()  app.mainloop() 

As you could see, labelExample and buttonExample have their parent widget as newWindow but not app .

Founder of DelftStack.com. Jinku has worked in the robotics and automotive industries for over 8 years. He sharpened his coding skills when he needed to do the automatic testing, data collection from remote servers and report creation from the endurance test. He is from an electrical/electronics engineering background but has expanded his interest to embedded electronics, embedded programming and front-/back-end programming.

Related Article — Tkinter Button

Источник

Оцените статью