'Creating RadioButtons with a loop but problem with them having the same value

I'm trying to make an exam sheet with "n" 4-option questions. I have created "n" sets of 4 horizontal Radiobuttons with a loop. the problem is everytime a certain radio button is selected, all other sets' radio buttons will also switch to that value. e.g.: For question 1 when option 4 (with value=4) is selected all other sets' Radiobuttons will switch to option 4. I think this is due to them having the same value.

How do you make them not all switch? Tried setting the variable of Radiobutton to IntVar at the end of the loop but it erases the original value that Radiobutton had so it's not useful (although it does make them all not switch at once). What should I do?

monokeyholder = IntVar()

for i in range(len(lickey)):

    ttk.Label(mainframe, text=(i + 1)).grid(row=i + 1, column=0)

    ttk.Radiobutton(mainframe, value=1, variable=monokeyholder,
                    command=Sett).grid(row=i + 1, column=1)

    ttk.Radiobutton(mainframe, value=2, variable=monokeyholder,
                    command=Sett).grid(row=i + 1, column=2)

    ttk.Radiobutton(mainframe, value=3, variable=monokeyholder,
                    command=Sett).grid(row=i + 1, column=3)

    ttk.Radiobutton(mainframe, value=4, variable=monokeyholder,
                    command=Sett).grid(row=i + 1, column=4)

Is there a way for them to not switch but also hold their value? Should I use different masters maybe or just do 200+ Radiobuttons manually (which I doubt is the only way).

Edit: Sett is defined to append the value of each selected button to a list. It does work as intended.



Solution 1:[1]

Tkinter uses the variable to know which radiobuttons belong in a set. Threfore, each row needs to use its own instance of IntVar. The simplest way to manage them is to store them in a list.

The solution looks something like this:

monokeyholder = []
for i in range(len(lickey)):

    var = tk.IntVar(value=0)
    monokeyholder.append(var)
    ...

    ttk.Radiobutton(..., value=1, variable=var, ...)
    ttk.Radiobutton(..., value=2, variable=var, ...)
    ttk.Radiobutton(..., value=3, variable=var, ...)
    ttk.Radiobutton(..., value=4, variable=var, ...)

With that, you can get the value for any row with something like this:

print(monokeyholder[3].get())

Here is a complete working example. When you run it, check any checkboxes you want and the click the "show values" button to see the values.

import tkinter as tk
from tkinter import ttk

root = tk.Tk()

def show_values():
    values.delete("1.0", "end")
    for i in range(10):
        values.insert("end", f"Row {i+1}: {monokeyholder[i].get()}\n")

maxrows = 10
mainframe = tk.Frame(root)
showbutton = tk.Button(root, text="Show values", command=show_values)
values = tk.Text(root, height=maxrows, width=20)

showbutton.pack(side="bottom")
mainframe.pack(side="left", fill="both", expand=True, padx=10, pady=10)
values.pack(side="right", fill="both", expand=True)

monokeyholder = []
for i in range(maxrows):

    var = tk.IntVar()
    monokeyholder.append(var)

    ttk.Label(mainframe, text=(i + 1)).grid(row=i, column=0)

    ttk.Radiobutton(mainframe, value=1, variable=var).grid(row=i, column=1)
    ttk.Radiobutton(mainframe, value=2, variable=var).grid(row=i, column=2)
    ttk.Radiobutton(mainframe, value=3, variable=var).grid(row=i, column=3)
    ttk.Radiobutton(mainframe, value=4, variable=var).grid(row=i, column=4)


root.mainloop()

screenshot of example

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1