My first ever question in here. To the point. I want to implement an interface with tkinter containing multiple groups of radio buttons. Every group will have three radio buttons (Good, Normal, Bad). After the code execution the user will choose the radio buttons he wants and at the end he presses a button to collect the values of all radio buttons so we could have a statistic view of how many, let's say "Good", have been selected. All the above should be implemented as much dynamically as it is possible.
The things i tried. I used generators for the:
Here's the code.
import tkinter as tk
from tkinter import ttk
my_list = ["Test 1", "Test 2", "Test 3"]
# Set up all the components of the UI.
root = tk.Tk()
root.title('Radio Buttons Test')
root.geometry("1024x768")
# Create counters for use in placing radio buttons.
# Generic counter for labels or wherever it might be useful.
def counter(listfile):
i = 0
for i in range(len(listfile) * 3 + 1):
if i != 0:
yield i
i +=1
count = counter(my_list)
#Counter for rows with even numbers.
def even_counter(listfile):
for i in range(len(listfile) * 2 + 1):
if i != 0 and i % 2 == 0:
yield i
even = even_counter(my_list)
#Counter for rows with odd numbers.
def odd_counter(listfile):
odd_numbers = []
for i in range(len(listfile) * 3 + 1):
if i > 2 and i % 2 != 0:
odd_numbers.append(i)
odd_lst = odd_numbers * 4
odd_lst.sort()
for x in odd_lst:
yield x
odd = odd_counter(my_list)
# Generating numbers to be used in radiobutton's variable naming.
def var_values(listfile):
var_numbers = []
for i in range(len(listfile) * 3 + 1):
var_numbers.append(i)
var_lst = var_numbers * 3
var_lst.sort()
for x in var_lst:
yield x
rb_var_values = var_values(my_list)
def labels(listfile):
for i in listfile:
label_text = tk.Label(root, text=str(next(count))+ '. ' + i, font=("Arial", 11))
label_text.grid(column=0, row=next(even), sticky="w", columnspan=3)
# Generate radio buttons.
rblst = []
var_value = 0
def radio_buttons(listfile):
global var
for rb in range(len(listfile)):
var = tk.IntVar(None)
var_value = next(rb_var_values)
var.set(var_value)
rb1 = ttk.Radiobutton(root, text="Good", variable=var, value=1)
rb2 = ttk.Radiobutton(root, text="Normal", variable=var, value=2)
rb3 = ttk.Radiobutton(root, text="Bad", variable=var, value=3)
rblst.extend([rb1,rb2,rb3])
comment = tk.Entry(root, width=60, borderwidth=3)
rb1.grid(column=0, row=next(odd))
rb2.grid(column=1, row=next(odd))
rb3.grid(column=2, row=next(odd))
comment.grid(column=3, row=next(odd), pady=5)
# Function for the command of "Stats" button.
def stat_btn():
for i in rblst:
print(f'ID is: {id(i)} and Variable is {var.get()}')
print('Length is',len(rblst))
# Create and place the "Stats" button.
bt = tk.Button(root, text="Stats", command=stat_btn)
bt.grid(column=5,row=47, sticky="se")
labels(my_list)
var_values(my_list)
radio_buttons(my_list)
root.mainloop()
By pressing the Stats button i get wrong results, meaning that only the last group of radio buttons affects the result of var.getand not the first and the second group. You think it's the variable or the value of the radio buttons that cause this problem? Will OOP implementation of the above code will make things easier to manage?
You can implement like this, You can copy this code and i hope this works.
import tkinter as tk
from tkinter import ttk
my_list = ["Test 1", "Test 2", "Test 3"]
root = tk.Tk()
root.title('Radio Buttons Test')
root.geometry("1024x768")
def counter(listfile):
i = 0
for i in range(len(listfile) * 3 + 1):
if i != 0:
yield i
i +=1
count = counter(my_list)
def even_counter(listfile):
for i in range(len(listfile) * 2 + 1):
if i != 0 and i % 2 == 0:
yield i
even = even_counter(my_list)
def odd_counter(listfile):
odd_numbers = []
for i in range(len(listfile) * 3 + 1):
if i > 2 and i % 2 != 0:
odd_numbers.append(i)
odd_lst = odd_numbers * 4
odd_lst.sort()
for x in odd_lst:
yield x
odd = odd_counter(my_list)
def var_values(listfile):
var_numbers = []
for i in range(len(listfile) * 3 + 1):
var_numbers.append(i)
var_lst = var_numbers * 3
var_lst.sort()
for x in var_lst:
yield x
rb_var_values = var_values(my_list)
def labels(listfile):
for i in listfile:
label_text = tk.Label(root, text=str(next(count))+ '. ' + i, font=("Arial", 11))
label_text.grid(column=0, row=next(even), sticky="w", columnspan=3)
rblst = []
var_values_list = [] # List to hold the var variables for each group
def radio_buttons(listfile):
global var
for rb in range(len(listfile)):
var = tk.IntVar(None)
var_value = next(rb_var_values)
var.set(var_value)
rb1 = ttk.Radiobutton(root, text="Good", variable=var, value=1)
rb2 = ttk.Radiobutton(root, text="Normal", variable=var, value=2)
rb3 = ttk.Radiobutton(root, text="Bad", variable=var, value=3)
rblst.extend([rb1, rb2, rb3])
comment = tk.Entry(root, width=60, borderwidth=3)
rb1.grid(column=0, row=next(odd))
rb2.grid(column=1, row=next(odd))
rb3.grid(column=2, row=next(odd))
comment.grid(column=3, row=next(odd), pady=5)
var_values_list.append(var) # Store the var variable for each group
def stat_btn():
for i, var in enumerate(var_values_list):
print(f'ID is: {id(rblst[i])} and Variable is {var.get()}')
print('Length is', len(rblst))
bt = tk.Button(root, text="Stats", command=stat_btn)
bt.grid(column=5, row=47, sticky="se")
labels(my_list)
var_values(my_list)
radio_buttons(my_list)
root.mainloop()