Elliptica
Elliptica

Reputation: 4332

How to Get Text Label from Selected Tkinter Radio Button?

I have created a generic class function for creating radio buttons using python tkinter. The following class code works fine:

import tkinter as tk

class MyGui:

    def __init__(self):  
    
        self.root = tk.Tk()

    def makeRadioButtons(self, list_choices, parent, on_select_function = None, **style_arguments):
        """ The on_select_fuction is what to do once a choice is made """
        
        self.radio_selection = tk.IntVar() # Use "self" or they'll all show as selected on hover
            
        use_value = 1 # start at 1, not index, since IntVar starts with 0
                      # Otherwise, the first button will be selected (since
                      # its value --- 0 --- will match IntVar)
        
        for choice in list_choices:
                
            chk = tk.Radiobutton(parent, 
                                 text = choice, 
                                 variable = self.radio_selection,
                                 value = use_value,
                                 command = on_select_function,
                                 **style_arguments)
            
            chk.pack()
            
            use_value += 1

        return self.radio_selection

    def start(self):
        
        self.root.mainloop()
        
    def stop(self):
        
        self.root.quit()
        self.root.destroy()

I make the radio buttons in a different file using the following code, storing the value of the selected button so that when the selection changes, I can print the value of the new selection:

gui = MyGui()

selected_value = gui.makeRadioButtons([
        "Apple",
        "Banana",
        "Carrot",
        "Dragonfruit"
    ],
    on_select_function = lambda: print(selected_value.get()),
    parent = gui.root)

The issue is that right now I can only print the selected button's value (in this case, a number) and I want to be able to print the text label. I know I could use StringVar to just store the text as the value, but that feels redundant to me, especially if (unlike in my example above) the radio text is long, not short.

I'm sure I could store the list of choices and then use the value to index into it, but I want to avoid that because technically the two pieces of code are separate and unaware of each other --- that is to say, the code that constructs the radio buttons shouldn't know how the buttons are internally implemented, and so it shouldn't assume a relationship between value and an index.

Is there a way to get the text label of a selected radio button, not just the value?

Upvotes: 0

Views: 978

Answers (2)

acw1668
acw1668

Reputation: 47093

You can simply pass the text of the radiobutton to the callback on_select_function:

class MyGui:
    ...
    def makeRadioButtons(...):
        ...
        for choice in list_choices:
               
            chk = tk.Radiobutton(parent, 
                                 text = choice, 
                                 variable = self.radio_selection,
                                 value = use_value,
                                 command = lambda v=choice: on_select_function(v),
                                 **style_arguments)
        ...

...
selected_value = gui.makeRadioButtons([
        "Apple",
        "Banana",
        "Carrot",
        "Dragonfruit"
    ],
    on_select_function = lambda v: print(selected_value.get(), v),
    parent = gui.root)

Upvotes: 1

PCM
PCM

Reputation: 3011

Look at this example:

It creates a range of radio buttons using for loop and appends it to a list. So when it is clicked it will get the text of the button in the list index -

from tkinter import *

root = Tk()
variable = IntVar()
variable.set(None)

def gettext(a):
    print(radiobutton_lists[a]['text']) # or you could use .cget()

radiobutton_lists = []

for i in range(6):
    rb = Radiobutton(root,text=i,command=lambda i=i:gettext(i),variable=variable,value=i)
    rb.pack()
    rb.deselect()
    radiobutton_lists.append(rb)

I think this is what you want.

Upvotes: 0

Related Questions