MEZIANE Yacine
MEZIANE Yacine

Reputation: 41

Tkinter Variable Observer

I tried to put a variable according to the observer information. Then this variable, I wish to use it in treatments and not to display it.

#coding:utf-8
import tkinter

app = tkinter.Tk()

def CountryChoice(*args):
   if observer.get() == 0:
       Country = "France"
   if observer.get():
       Country = "United Kingdom"

observer = tkinter.StringVar()
observer.trace("w", CountryChoice)

FranceRadio = tkinter.Radiobutton(app, text="France", value=0, variable=observer)
UKRadio = tkinter.Radiobutton(app, text="UK", value=1, variable=observer)

FranceRadio .grid(row=0, column=0)
UKRadio .grid(row=0, column=1)

#def treaitement():
   #i would like to reuse the variable Country here but I can not get it.

print(Country)  #==> NameError: name 'Country' is not defined

app.mainloop()

The goal is to retrieve the Country variable when the user places the mouse on a button. The next goal is to add a launch button that will launch a process that depends on the choice of the radio button. But I can not get the Country variable.

Upvotes: 1

Views: 586

Answers (2)

martineau
martineau

Reputation: 123501

There are several things preventing the code in your question from working.

The NameError is occurring because the global variable Country doesn't exist when the print(Country) call is executed. That can be fixed by simply defining the variable beforehand—probably somewhere near the beginning of the script.

Somewhat related to that issue, is the fact that in the CountryChoice() function, Country is considered a local variable, so setting its value there doesn't affect the global variable with the same name. That can be fixed by declaring the variable to be global at the beginning of the function.

Lastly, when using Radiobutton widgets, the type of value option should match the type of tkinter variable being used. In this case, the values are integers, so I changed the variable type of observer from tk.StringVar to tk.IntVar.

I've made those changes and added a call to a treatment() function to the end of the CountryChoice() function to print the current value everytime it's called.

#coding:utf-8
import tkinter as tk

app = tk.Tk()

Country = None  # Declare global variable.

def CountryChoice(*args):
    global Country

    if observer.get() == 0:
        Country = "France"
    elif observer.get() == 1:
        Country = "United Kingdom"

    treatment()  # Use current value of Country.

observer = tk.IntVar()  # Use IntVar since Radiobutton values are integers.
observer.trace("w", CountryChoice)

FranceRadio = tk.Radiobutton(app, text="France", variable=observer, value=0)
UKRadio = tk.Radiobutton(app, text="UK", variable=observer, value=1)

FranceRadio.grid(row=0, column=0)
UKRadio.grid(row=0, column=1)

def treatment():
    # Reuse the variable Country.
    print(Country)

app.mainloop()

In closing, I'd like to make a few suggestions.I strongly suggest that you read and start following the PEP 8 - Style Guide for Python Code recommendations, particularity the sections about Naming Conventions and Code Layout. This will make your code easier to work on and maintain—as well as easier for others to read.

Likewise, the accepted answer to the question Best way to structure a tkinter application? has some excellent suggestions from a tkinter expert on the best way to structure tkinter applications that would, if you followed them, eliminate the need to use most global variables (which are considered by many to be a poor programming practice).

Upvotes: 1

Matt M
Matt M

Reputation: 710

To start, you are treating your country variable as a global but it's not. Also it isn't defined anyway before the mainloop.

def CountryChoice(*args):
    global Country
    obs = observer.get()
   if int(obs) == 0:
        Country = "France"
    if int(obs) == 1:
        Country = "United Kingdom"

This is a start. Now you can't ask to print Country until it is defined, though. I suggest you do not declare 'Country' a global, and simply just launch your functions from your CountryChoice function

Like

if int(obs) == 1:
        someFunction("United Kingdom")

Upvotes: 2

Related Questions