2

I would like to have a window with a single button (with text "Click"). When I click the button a new window should open. And in that second window I would like to have 2 radiobuttons and a button (with text "Print"). Clicking that button ("Print") should print the current value of the variable my_variable, which indicates which Radiobutton is choosen.

The first code is missing the first window, but it prints out the correct values. The second code, where I added the first window (with the button "Click" opening the second window) prints always the default value of the variable my_variable. What should I change to get the current value every time a press the button "Print"?

I use tkinter with Python 3.7.

Working code:

import tkinter as tk

def function():
    """That function print the current value of my_variable, depending on which radiobutton was choosen."""
    value = my_variable.get()
    print(value)   

window = tk.Tk()
window.title("Title")
window.geometry('200x200')

my_variable = tk.IntVar(value=0)

rbtn1 = tk.Radiobutton(window, text='one', value=1, variable=my_variable)
rbtn1.grid(row=0, column=0)
rbtn2 = tk.Radiobutton(window, text='two', value=2, variable=my_variable)
rbtn2.grid(row=1, column=0)


button = tk.Button(window, text="Print", command=function)
button.grid(row=2, column=0)
window.mainloop()

Not working code:

import tkinter as tk

def on_click():
    def function():
    """That function shoud print the current value of my_variable, depending on which radiobutton was choosen. But it prints the default value instead."""
        value = my_variable.get()
        print(value)   

    window = tk.Tk()
    window.title("Title")
    window.geometry('200x200')

    my_variable = tk.IntVar(value=0)

    rbtn1 = tk.Radiobutton(window, text='one', value=1, variable=my_variable)
    rbtn1.grid(row=0, column=0)
    rbtn2 = tk.Radiobutton(window, text='two', value=2, variable=my_variable)
    rbtn2.grid(row=1, column=0)


    button = tk.Button(window, text="Print", command=function)
    button.grid(row=2, column=0)

window_main = tk.Tk()
window_main.title("Title main")
window_main.geometry('400x400')

button = tk.Button(window_main, text="Click", command=lambda: on_click())
button.grid(row=0, column=0)

window_main.mainloop()
martineau
  • 119,623
  • 25
  • 170
  • 301
Monika
  • 29
  • 5

2 Answers2

4

The problem is you're calling tk.Tk() twice. When you want to create another window, use tk.Toplevel() instead.

To avoid needing to do that, just change the one line indicated below:

import tkinter as tk

def on_click():
    def function():
        """That function should print the current value of my_variable, depending on which radiobutton was chosen. But it prints the default value instead."""
        value = my_variable.get()
        print(value)

    window = tk.Toplevel()  ##### CHANGED.
    window.title("Title")
    window.geometry('200x200')

    my_variable = tk.IntVar(value=0)

    rbtn1 = tk.Radiobutton(window, text='one', value=1, variable=my_variable)
    rbtn1.grid(row=0, column=0)
    rbtn2 = tk.Radiobutton(window, text='two', value=2, variable=my_variable)
    rbtn2.grid(row=1, column=0)


    button = tk.Button(window, text="Print", command=function)
    button.grid(row=2, column=0)

window_main = tk.Tk()
window_main.title("Title main")
window_main.geometry('400x400')

button = tk.Button(window_main, text="Click", command=lambda: on_click())
button.grid(row=0, column=0)

window_main.mainloop()

If you want to understand why you should avoid calling Tk() more than once, see the answer to Why are multiple instances of Tk discouraged?

martineau
  • 119,623
  • 25
  • 170
  • 301
0

See:

  • When you click a button in the main window, it calls on_click.
  • Inside on_click, you every time reassign the variable value: my_variable = tk.IntVar(value=0).

This is why the value of my_variable is not preserved between clicks of the button in the main window.

You need to keep my_variable outside on_click, and initialize it once, not on every click.

A nice way to do that is to make on_click accept it as a parameter: def on_click(my_variable), and command=lambda: on_click(my_variable).

A quick and pretty dirty way is to use global; it's acceptable in a throwaway script, but will quickly become ugly and hard to reason about.

9000
  • 39,899
  • 9
  • 66
  • 104
  • I've change it, but unfortunately it didn't help. – Monika Jan 06 '20 at 22:30
  • 9000: The question isn't about preserving the value of `my_variable` between calls of `on_click()` and there's no need to utilize global variables to fix the problem. – martineau Jan 06 '20 at 22:56