Python Forum
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Looping over radio buttons
#1
I have a series of radio buttons on a grid, using custom tkinter.

I am setting each one up onto the grid using the following code:

        self.header = customtkinter.CTkLabel(self, text=self.header_name)
        self.header.grid(row=0, column=0, padx=10, pady=10)

        self.radio_button_var = customtkinter.StringVar(value="")

        self.radio_button_1 = customtkinter.CTkRadioButton(self, text=graph_types[0][0], value=graph_types[0][1], variable=self.radio_button_var)
        self.radio_button_1.grid(row=1, column=0, padx=10, pady=10, sticky="W")
        self.radio_button_2 = customtkinter.CTkRadioButton(self, text=graph_types[1][0], value=graph_types[1][1], variable=self.radio_button_var)
        self.radio_button_2.grid(row=2, column=0, padx=10, pady=10, sticky="W")
        self.radio_button_3 = customtkinter.CTkRadioButton(self, text=graph_types[2][0], value=graph_types[2][1], variable=self.radio_button_var)
        self.radio_button_3.grid(row=3, column=0, padx=10, pady=10, sticky="W")
        self.radio_button_4 = customtkinter.CTkRadioButton(self, text=graph_types[3][0], value=graph_types[3][1], variable=self.radio_button_var)
        self.radio_button_4.grid(row=4, column=0, padx=10, pady=10, sticky="W")
        self.radio_button_5 = customtkinter.CTkRadioButton(self, text=graph_types[4][0], value=graph_types[4][1], variable=self.radio_button_var)
        self.radio_button_5.grid(row=5, column=0, padx=10, pady=10, sticky="W")
        self.radio_button_6 = customtkinter.CTkRadioButton(self, text=graph_types[5][0], value=graph_types[5][1], variable=self.radio_button_var)
        self.radio_button_6.grid(row=6, column=0, padx=10, pady=10, sticky="W")
        self.radio_button_7 = customtkinter.CTkRadioButton(self, text=graph_types[6][0], value=graph_types[6][1], variable=self.radio_button_var)
        self.radio_button_7.grid(row=7, column=0, padx=10, pady=10, sticky="W")
This continues for some time.

As you can see, all I am doing is altering the position and value of each radio button. So, these lines are almost identical.

I know I should be able to loop over two lines and create the same concept but, for the life of me, I cannot see how.

I started trying with a dictionary but then got confused.

graph_types is a 2D list that could easily become a dictionary; with the key being each radio button's name/number but is there a better way?

Or how would this look?

Sorry, brain is burnt out today.
Reply
#2
You could try something like

buttons = []
for graph in graph_types:   
    buttons.append(customtkinter.CTkRadioButton(self, text=graph[0], value=graph[1], variable=self.radio_button_var))

for index, button in enumerate(buttons, start=1):
    button.grid(row=index, column=0, padx=10, pady=10, sticky="W")
Reply
#3
buttons = [RadioButton(self, text=gt[0], value=gt[1], variable=self.radio_button_var)) for gt in graph_types]
for index, button in enumerate(buttons, start=1):
button.grid(row=index, column=0, padx=10, pady=10, sticky="W")[/python]
Reply
#4
self.header = customtkinter.CTkLabel(self, text=self.header_name)
self.header.grid(row=0, column=0, padx=10, pady=10)

self.radio_button_var = customtkinter.StringVar(value="")
self.radio_buttons = []
for index, graph_type in enumerate(graph_types, 1):
    text, value = graph_type
    radio_button = customtkinter.CTkRadioButton(
        self, text=text, value=value, variable=self.radio_button_var
    )
    radio_button.grid(row=index, column=0, padx=10, pady=10, sticky="W")
    self.radio_buttons.append(radio_button)
Reply
#5
I used @Yoriz approach, since it was closer to my original attempt; though this is also similar to the first suggestion, which I also tried.

When I attempted the first one, I encountered a problem that I thought this one would resolve, but it didn't.

The issue comes about in that I have 36 different graph types I need to consider. Having these in a single column is, therefore, not an option.

I introduced two variables, row and col, incrementing these accordingly (row by 1 each time, reset to 0 when row == 10 and incremented col by 1.

This worked nicely, with the code now looking like this...

		self.radio_buttons = []
		col = 0
		row = 0

		for graph_type in graph_types:
			text, value = graph_type
			radio_button = customtkinter.CTkRadioButton(self, text=text, value=value, variable=self.radio_button_var)
			radio_button.grid(row=row, column=col, padx=5, pady=5, sticky="W")
			self.radio_buttons.append(radio_button)
			row += 1
			if (row == 20):
				col += 1
				row = 0
Here's the issue, if I select one radio button then, on occasion, others are also selected?!?

This does not happen if I simply use the index as the row reference (though this runs off the page).

The references to each button in the list self.radio_buttons are unique and this is not changing. The relationship between the active buttons is not apparent ([5, 25, 27], [22, 36]) and, as you can see from that list, this only occurs for 5 buttons?!?

Any ideas?

Total code is here...

import customtkinter

graph_types = [["Tbol-age - tauir-age", "TLTAge"], ["Makes the coffee", "MtC"], ["Lbol - Lshock (Class 1 data)", "LL1"], ["Lbol - CO Momentum","LCM"], ["Tbol - Lbol","TL"], ["Menv - H2","MH2"], ["Lbol - Lshock (Class 0 data)","LL0"], ["Tbol - H2","TH2"], ["Mcor - Lbol + Molinari data + Elia data","MLME"]
, ["Probability Diagram","Prob"], ["Mstar - Tstar","MS_TS"], ["Mstar - Rstar","MS_RS"], ["Fco * x / Lbol vs Menv / Lbol^0.6","FLML"], ["Lbol - Tbol (combined)","LTC"], ["Mstar - Lbol","MS_L"], ["Mcor - Lbol + (M + E) - different axes","ML"], ["Mcor - Lbol ???","ML_Unknown"], ["TEST Time - Rstar","TEST1"], ["TEST Time - Lint","TEST2"], ["Menv - Lbol - L(Ly) / Lbol","MLLL"], ["Mstar - Lbol / Ledd","MLL"], ["Tstar - Lbol","TS_L"], ["Time - Tbol","TT"], ["Tbol - Mclump / Lbol","TML"], ["Tstar - Lint","TL"], ["Single histogram for L/M","SLM"], ["Time - Lbol","TL"], ["Tbol isotherms","TI"], ["HR Diagram for Lint and Lbol tracks","HR"], ["Mstar - vjet","MS_V"], ["Time - Lbol / Mcor","TLM"], ["Disk radial profiles","DRP"], ["Lbol - Lshock","LL"], [" Time - Mdot","TMdot"], ["Lbol - L(Ly)","LLLy"], ["Tstar - Lint","TS_L"]]

customtkinter.set_default_color_theme("dark-blue")  # Themes: "blue" (standard), "green", "dark-blue"
customtkinter.set_appearance_mode("system")			# Appearance: "system" (standard), "dark", "light"

class RadioButtonFrame(customtkinter.CTkFrame):
	
	def __init__(self, *args, header_name="RadioButtonFrame", **kwargs):
		super().__init__(*args, **kwargs)
        
		self.header_name = header_name

		self.header = customtkinter.CTkLabel(self, text=self.header_name)
		self.header.grid(row=0, column=0, padx=5, pady=5)

		self.radio_button_var = customtkinter.StringVar(value="")
 
		self.radio_buttons = []
		col = 0
		row = 0

		for graph_type in graph_types:
			text, value = graph_type
			radio_button = customtkinter.CTkRadioButton(self, text=text, value=value, variable=self.radio_button_var)
			radio_button.grid(row=row, column=col, padx=5, pady=5, sticky="W")
			self.radio_buttons.append(radio_button)
			row += 1
			if (row == 20):
				col += 1
				row = 0
				
		for button in self.radio_buttons:
			print (button)


class App(customtkinter.CTk):
	def __init__(self):
		super().__init__()

		self.geometry("1024x768")
		self.title("RadioButtonFrame test")

# create radio button frame 1 with print button
		self.radio_button_frame_1 = RadioButtonFrame(self, header_name="Graph Selections")
		self.radio_button_frame_1.grid(row=0, column=0, padx=20, pady=20)

		self.frame_1_button = customtkinter.CTkButton(self, text="Print value of frame", command=self.print_value_frame)
		self.frame_1_button.grid(row=1, column=0, padx=20, pady=10)

	def print_value_frame(self):
		print(f"Frame 1 value: {self.radio_button_frame_1.get_value()}")


if __name__ == "__main__":
	app = App()
	app.mainloop()

Attached Files

Thumbnail(s)
   
Reply
#6
You have CTkRadioButton that have the same value
For instance these all share the value "TL"
["Tbol - Lbol", "TL"]
["Tstar - Lint", "TL"]
["Time - Lbol", "TL"]

Also, you have your header label on row 0 and then place a radio button over the top of it also on row 0
change the radio buttons starting row from 0
col = 0
row = 0
to 1
col = 0
row = 1
and the condition row 0
if row == 20:
    col += 1
    row = 0
to 1
if row == 20:
    col += 1
    row = 1
Reply
#7
Thank you so much!
Sometimes you can't see the woods for the trees.
Reply
#8
Don't you think a combobox, or maybe a listbox would be a better choice? I limit radio buttons to 5 options or less.
Reply
#9
(Jan-07-2023, 04:32 PM)deanhystad Wrote: Don't you think a combobox, or maybe a listbox would be a better choice? I limit radio buttons to 5 options or less.

Yes, possibly; I will ponder on that one (especially as the number is likely to increase). Smile
Reply


Possibly Related Threads…
Thread Author Replies Views Last Post
  packet radio communication EmpireAndrew 1 2,193 Nov-01-2019, 06:35 PM
Last Post: micseydel
  Internet radio script ahim 3 3,419 Jul-14-2018, 06:13 PM
Last Post: ahim
  Buttons or Radio Buttons on Tkinter Treeview draems 0 3,384 Oct-31-2017, 04:06 AM
Last Post: draems
  tkinter - Make circle for radio button bigger Raptor88 5 14,194 Mar-07-2017, 12:13 PM
Last Post: metulburr

Forum Jump:

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020