I'm creating a show tracker, and on the actual tracker page I want to load a scrolling ScrolledText box with a checkbox for each episode retrieved (I have chosen a ScrolledText box as it allows me to scroll if the amount of episodes fills over the screen). The code below does this perfectly, however each checkbox is referred to as the same variable, and thus every time I click one episode number, it selects all of them.
for alignment in range(1,int(showDisplay_episodesAmount) 1):
# create a radio button
self.showDisplay.episodeCheckbox = Checkbutton(self.showDisplay.episodesScrollBox, text=alignment,variable=var1, onvalue=1, offvalue=0)
self.showDisplay.episodeCheckbox.grid(column=0, row=grid_column)
self.showDisplay.episodesScrollBox.window_create('end', window=self.showDisplay.episodeCheckbox)
self.showDisplay.episodesScrollBox.insert('end', '\n')
grid_column = 1
I would like each checkbox to correspond to a separate episode number (such as checkbox 1 referring to episode 1, etc.), created in a for loop, as I cannot predetermine the amount of episodes for a wide variety of shows.I have tried the list approach, making this code, which both doesn't create separate checkboxes, and disables the scrollbar:
for alignment in range(1,int(showDisplay_episodesAmount) 1):
# create a radio button
self.showDisplay.episodeCheckbox[alignment] = {}
self.showDisplay.episodeCheckbox[alignment]['name'] = alignment
self.showDisplay.episodeCheckbox[alignment]['checkbox'] = Checkbutton(self.showDisplay.episodesScrollBox, text=alignment,variable=var1, onvalue=1, offvalue=0).grid(column=0, row=grid_column)
#self.showDisplay.episodesScrollBox.window_create('end', window=self.showDisplay.episodeCheckbox[alignment])
self.showDisplay.episodesScrollBox.insert('end', '\n')
grid_column = 1
How could I make each checkbox generated distinct and not linked to each other?
CodePudding user response:
I think you can use a list instead of the variable. Then you can set each episode to one item in the list. like this:
listofvar = []
for alignment in range(1,int(showDisplay_episodesAmount) 1):
listosvar.append(tk.StringVar())
# create a radio button
self.showDisplay.episodeCheckbox = Checkbutton(self.showDisplay.episodesScrollBox, text=alignment,variable=listofvar[alignment-1], onvalue=1, offvalue=0)
self.showDisplay.episodeCheckbox.grid(column=0, row=grid_column)
self.showDisplay.episodesScrollBox.window_create('end', window=self.showDisplay.episodeCheckbox)
self.showDisplay.episodesScrollBox.insert('end', '\n')
grid_column = 1
Now each checkbox will define one item in the list ...
Hope I helped.
Jonathan
CodePudding user response:
You can use the simple versione of Jhonatan but you can also do something more sophisticated like creating a dictionary in which the key is the progressive counter of episode (your allignment) and the value is the checkboxed itself, from whick you can access the state. I don't use plain tk checkboxes but rather ttk, so here it's an example with ttk:
from tkinter import ttk
checkboxes_dictionary={}
for alignment in range(1,int(showDisplay_episodesAmount) 1):
checkboxes_dictionary[alignment]=ttk.Checkbutton(Checkbutton(self.showDisplay.episodesScrollBox, text=alignment)
checkboxes_dictionary[alignment].pack()
Here I'm assuming you are interested in only showing the state of the checkboxes so I omitted the var.
You can access the state of your checkboxes with this line:
checkboxes_dictionary[my_episode].state()
Where of course my_episode is an integer between 0 and showDisplay_episodesAmount. You can also sweep this dictionary to print the status of all the episod (checked/unchecked).
Final note, in ttk the return of the state() method is not binary, rather is a string that has many values ("selected", "focus" and many others, and two or more of them can coexist so the output will be a list of these string. Look at the documentation
I haven't check my code so please review it