Ivan Castro
Ivan Castro

Reputation: 615

python tkinter.Radiobutton can't get value

I'm writing a python code with tkinter (python3) but I have some problems. I have two classes _MainScreen and _RegisterScreen (this last is nested in _MainScreen). In _RegisterScreen I had implemented a simple question with tkinter.Radiobutton (choose your sex: male, female). The idea is to catch the user selection, but when I run the script, the value assigned to the variable is empty (""). However, if I run the class _RegisterScreen alone, it works. I hope you can show me where is my error. Thanks in advance.

Here is an abstraction (32 lines) of my code (250 lines):

import tkinter

class _MainScreen(tkinter.Frame):
    def __init__(self):
        self.root = tkinter.Tk()
        self.new_account(self.root)
        self.root.mainloop()
    def new_account(self, frame):
        tkinter.Button(frame, text="Create new account",
            command=self.create_new_account).pack(anchor="center", pady=(0,15))
    def create_new_account(self):
        _RegisterScreen()

class _RegisterScreen(tkinter.Frame):
    def __init__(self):
        self.root = tkinter.Tk()
        tkinter.Label(self.root, text="Sex").grid(row=1, padx=(0,10), sticky="w")
        self.sex_option = tkinter.StringVar()
        tkinter.Radiobutton(self.root, text="Male", variable=self.sex_option,
            value="Male", command=self._selected).grid(row=1, column=1)
        tkinter.Radiobutton(self.root, text="Female", variable=self.sex_option,
            value="Female", command=self._selected).grid(row=1, column=2)
        tkinter.Button(self.root, text="Submit",
            command=self._login_btn_clickked).grid(row=3, columnspan=4, pady=20)
        self.root.mainloop()
    def _login_btn_clickked(self):
        sex = self._selected()
        print(sex)
    def _selected(self):
        return self.sex_option.get()

_MainScreen()
#_RegisterScreen() # comment the above line and uncomment this line 
                   # to test the _RegisterScreen object alone.

Upvotes: 1

Views: 2119

Answers (1)

Gunner Stone
Gunner Stone

Reputation: 1005

After doing some research on how tkinter's RadioButton widget works, I believe I have a solution to your problem:

Here's your new _RegisterScreen function:

class _RegisterScreen(tkinter.Frame):

    def __init__(self):
        self.gender = "NA" #Variable to be changed upon user selection

        self.root = tkinter.Tk()
        tkinter.Label(self.root, text="Sex").grid(row=1, padx=(0,10), sticky="w")

        self.sex_option = tkinter.StringVar()

        #This Radiobutton runs the setMale function when pressed
        tkinter.Radiobutton(self.root, text="Male", variable=self.sex_option,
            value="Male", command=self.setMale).grid(row=1, column=1)

        #This Radiobutton runs the setFemale function when pressed
        tkinter.Radiobutton(self.root, text="Female", variable=self.sex_option,
            value="Female", command=self.setFemale).grid(row=1, column=2)

        tkinter.Button(self.root, text="Submit",
            command=self._login_btn_clickked).grid(row=3, columnspan=4, pady=20)
        self.root.mainloop()

    def _login_btn_clickked(self):
        sex = self.gender #gets the value stored in gender and assigns it to sex
        print(sex)

    def setMale(self):
        self.gender="Male" #sets gender to Male

    def setFemale(self):
        self.gender="Female" #sets gender to Female

Ultimately, you want to run 2 separate functions for either RadioButton.

When the Male Radiobutton gets clicked, it runs the setMale function.

When the Female Radiobutton gets clicked, it runs the setFemale function.

I believe you were confused about what RadioButton's variable and value attributes actually are (as was I before looking further into this).

I learned more about what those those do in this video: https://www.youtube.com/watch?v=XNF-y0QFNcM

I hope this helps! ~Gunner

Upvotes: 1

Related Questions