How to get values from a Toplevel Tkinter Window

When creating multiple windows using Toplevel in your Tkinter applications, you may get confused in how to pass various values or data between the Main Window and the Toplevel widget. There are various solutions to this problem, which we will discuss in this tutorial.


Get Values from Tkinter TopLevel – Method#1

In this first example, we have a Settings window and a Main Window. Clicking on the Settings button in the Main Window will create a new TopLevel Window (the Settings Window). The code for this part is shown below.

    def openSettings(self):
        self.settings = SettingsWindow(self.update)

As you can see, we have passed an extra parameter to the Settings Window. This is not just any regular parameter though, it is actually a reference to the update() function in the Main Window.

    def update(self, n):
        self.SettingsValue = n
        print(self.SettingsValue)

The update function is shown in the code above. Basically we will now be calling the update() function of the Main Window from the Settings Window.

We will give pass a parameter to the update() function, called “n“, which will then be saved inside the Main Window’s self.SettingsValue parameter. This ensures we have access to the value even after the Settings Window has been destroyed.

What exactly is this value that we are passing into the update function? Well, since this is just a tutorial, we only have a pair of RadioButtons in our Settings window. Clicking on either radiobutton will trigger the update() function, and let the Main Window know which radiobutton has been clicked.


Here is the full code. We have also thrown in some bonus code, which shows you how to modify the Settings window from the Main Window!

import tkinter as tk
from tkinter.simpledialog import askinteger
 
class SettingsWindow:
    def __init__(self, func):
        self.win = tk.Toplevel()
        self.func = func
 
        frame = tk.Frame(self.win)
        frame.pack(padx=5, pady=5)
        self.label=tk.Label(frame, text="Settings Window")
        self.label.pack(padx=20, pady=5)
 
        self.var = tk.IntVar()
        radio=tk.Radiobutton(frame, text = "Option 1", value = 1, 
                             variable=self.var, command=self.ParentFunc)
        radio.pack(padx = 10, pady = 5)
        radio2=tk.Radiobutton(frame, text = "Option 2", value = 2,
                              variable=self.var, command=self.ParentFunc)
        radio2.pack(padx = 10, pady = 5)
 
    def ParentFunc(self):
        self.func(self.var.get())
 
 
class MainWindow:
    def __init__(self, master):
        self.master = master
        self.settings = None
        self.SettingsValue = None
 
        self.frame = tk.Frame(self.master, width=200, height=200)
        self.frame.pack()
 
        self.button = tk.Button(self.frame, text="Settings Window", 
                                command=self.openSettings)
        self.button.place(x=50, y=50)
 
        self.button2 = tk.Button(self.frame, text = "Update Settings", 
                                command = self.updateLabelinSettings)
        self.button2.place(x=50, y=150)
 
 
    def update(self, n):
        self.SettingsValue = n
        print(self.SettingsValue)
 
    def openSettings(self):
        self.settings = SettingsWindow(self.update)
 
    def updateLabelinSettings(self):
        prompt = askinteger("Input", "Input an Integer")
        if self.settings != None:
            self.settings.label.configure(text="Updated")
 
root = tk.Tk()
window = MainWindow(root)
root.mainloop()

Keep in mind the update function does not have to have the same name inside the Settings window. For example, we gave it the name “func” inside the Settings Window’s __init__ function.

Hint: Instead of passing in a function or variable name to the TopLevel window, you can instead pass in self, which is basically a reference to the Main Window. You could use this technique to access any function or variable declared using self from the TopLevel Window.


Get Values from another Window – Method#2

Here is another approach we can use to get values from a Top Level Window. Instead of making a separate class, we made a function for the Top Level window (although either approach will work with this method).

    def onClick(self):
        var, note = Settings()
        print(f"Entry Widget: {note.get()}  RadioButton: {var.get()}")

This is the onClick() function that will create the Settings Window. Now, unlike last time we are actually receiving some proper values from the Settings window. These are the tkinter variables which hold the values for RadioButtons/CheckButtons/Entry Fields etc.

But the question here, is that how are we supposed to return these values from the Settings Window? And more importantly, “when” do we return these values? The solution to this problem is the wait_window() method.

def Settings():
    settingsWindow = tk.Toplevel()
    ... 
    ... 
    ...
    settingsWindow.wait_window()
    print("finished waiting...")
    return (var, evar)

Including this at the very end of the program, right before the return statement will halt the execution of the program until the Settings Window has been closed (either through the button which calls the destroy method, or the quit icon). These values will then be returned to the Main Window.

Here is the whole code:

import tkinter as tk 

class Window(tk.Frame):
    def __init__(self, *args, **kwargs):
        tk.Frame.__init__(self, *args, **kwargs)
        button= tk.Button(self, text="Open window", command=self.onClick)
        button.pack(padx = 50, pady = 50)

    def onClick(self):
        var, note = Settings()
        print(f"Entry Widget: {note.get()}  RadioButton: {var.get()}")

def Settings():
    settingsWindow = tk.Toplevel()
    tk.Label(settingsWindow, text ="Settings Window").grid(row=0)

    var = tk.IntVar()
    tk.Radiobutton(settingsWindow, text="Option1", variable=var,
                   value=1).grid(row=2, sticky="w",padx=5,pady=5)
    tk.Radiobutton(settingsWindow, text="Option2", variable=var, 
                   value=2).grid(row=3, sticky="w",padx=5,pady=5)

    evar = tk.StringVar()
    note = tk.Entry(settingsWindow, width=30, 
                    textvariable=evar).grid(row=6,padx=5,pady=5)

    Button = tk.Button(settingsWindow, text ="Submit Data", 
                       command = settingsWindow.destroy).grid(row=7)

    settingsWindow.wait_window()
    print("finished waiting...")
    return (var, evar)

root = tk.Tk()
Window(root).pack(side="top", fill="both", expand=True)
root.mainloop()

This marks the end of the Get values from a Toplevel Tkinter Window Tutorial. Any suggestions or contributions for CodersLegacy are more than welcome. Questions regarding the tutorial content can be asked in the comments section below.

Subscribe
Notify of
guest
2 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments