Search code examples
pythontkinterradiobuttonlist

Python - Tkinter: How can I create multiple radiobuttons?


Me again. :p I've define RadioButtons in a group to reduce my code. But how could I create multiple radioButtons in this way? For example I want to create two lists but in both I want only choice one choice. Here's my code:

from Tkinter import *

master = Tk()
var = IntVar()
var.set(1)#Wahl inizialisieren
scrollbar = Scrollbar(master)
scrollbar.pack(side=RIGHT, fill=Y)

master.geometry('1000x500') #Abmessung Fenster
master.title('test') #Tittel Fenster


def create_window(): #Definion und Festlegung neues Fenster
    toplevel = Toplevel()
    toplevel.title('result')
    toplevel.geometry('1500x1000')
    toplevel.focus_set()

   sex = [
    ("male",1),
    ("female",2),
    ("male1",3),
    ("female1",4),
]

test = [
    ("test",5),
    ("test1",6),
    ("test2",7),
    ("test3",8),
]

def ShowChoice():
    print var.get()

#Erzeugung
Checkliste----------------------------------------------------------------

Label(master,
      text='''choose one answer:''',
      padx = 20).pack()

for txt, val in sex:
    Radiobutton(master,
                text=txt,
                justify = LEFT,
                padx = 20,
                variable=var,
                variable=v,
                command=ShowChoice,
                value=val).pack(anchor=N)

Label(master,
      text='''choose one answer:''',
      padx = 20).pack()

for txt, val in test:
    Radiobutton(master,
                text=txt,
                justify = LEFT,
                padx = 20,
                variable=var,
                variable=v1,
                command=ShowChoice,
                value=val).pack(anchor=N)



#-------------------------------------------------------------------------

Button(master, text='forward', command=create_window).pack(padx=5, 
anchor=N, pady=4)


master.mainloop()

Solution

  • You just need to give each Radiobutton group its own variable. But then how does ShowChoice know what variable to call .get() on? Well, one way to handle that is to make the command callback function a lambda that has the variable as a default argument. And while we're doing that we might as well pass the txt as a default arg too.

    from __future__ import print_function
    import Tkinter as tk
    
    master = tk.Tk()
    
    sex = [
        ("male", 1),
        ("female", 2),
        ("male1", 3),
        ("female1", 4),
    ]
    
    test = [
        ("test", 5),
        ("test1", 6),
        ("test2", 7),
        ("test3", 8),
    ]
    
    def ShowChoice(text, v):
        print(text, v.get())
    
    varsex = tk.IntVar()
    varsex.set(sex[0][1])
    
    tk.Label(master, text='Choose one answer:').pack()
    
    for txt, val in sex:
        tk.Radiobutton(master, text=txt, variable=varsex, value=val,
            command=lambda t=txt, v=varsex: ShowChoice(t, v)).pack(anchor=tk.N)
    
    vartest = tk.IntVar()
    vartest.set(test[0][1])
    
    tk.Label(master, text='Choose one answer:').pack()
    
    for txt, val in test:
        tk.Radiobutton(master, text=txt, variable=vartest, value=val,
            command=lambda t=txt, v=vartest: ShowChoice(t, v)).pack(anchor=tk.N)
    
    master.mainloop()
    

    I have edited out various things in your program that aren't relevant to your problem. It's a Good Idea to post a MCVE that focuses on the actual program, rather than bloating your question code with irrelevant stuff.

    I've converted your print statement to a print function call to make it easier to run your program on Python 3, all you need to do is change Tkinter to tkinter in the import statement.


    I also got rid of that "star" import. Sure, plenty of Tkinter examples use "star" import, but it's not recommended: it pollutes your namespace with over 170 names in Python 2 (and around 130 names in Python 3), which is messy and can lead to name collisions. And although there's a little more typing when you do import Tkinter as tk it makes the code easier to read because it's obvious which names are Tkinter names.