Tkinter dynamic scrollbar depending on number of entries - python

I am trying to create a little GUI that takes a various number of inputs from entries. The number of entries should be flexible between zero and 32, and the user can add entries via a button (simplified version of the program).
The problem is that with 32 entries die GUI gets quite long and I'd like to add a scrollbar so to minimize the size of the GUI window and the user can scroll through the entries.
I have developed an example based on code I found on this website but I cannot get the scrollbar to work.
I simplified version of my code is below.
Thanks for your help!
from tkinter import *
class SlowCH_Manager(Canvas):
"""
Manages a variable number of slow channel massages
"""
def __init__(self,master=None,**kwargs):
Canvas.__init__(self,master,**kwargs)
self.frame = Frame(self)
self.create_window(0,0,anchor=N+W,window=self.frame)
self.row = 0
self.widgets = []
self.max = 32
self._init_entries()
def _init_entries(self):
"""
initialize the input area with labels and perhaps default values
"""
label_id = Label(self.frame, text='message ID').grid(row = self.row, column = 1)
label_msg = Label(self.frame, text='message data').grid(row = self.row, column = 2)
self.row += 1
def add_entry(self):
"""
Dynamically add entry to GUI until max number of entries is arrived.
By SENT specification max 32 slow channel messages are allowed.
"""
if len(self.widgets) >= self.max:
print('Im full')
else:
label = Label(self.frame, text=str(len(self.widgets))).grid(row = self.row, column = 0)
entry_id = Entry(self.frame)
entry_id.grid(row = self.row, column = 1)
entry_data = Entry(self.frame)
entry_data.grid(row = self.row, column = 2)
self.row += 1
self.widgets.append(entry_id)
def _ypos(self):
return sum(x.winfo_reqheight() for x in self.widgets)
if __name__ == "__main__":
root = Tk()
manager = SlowCH_Manager(root)
manager.grid(row=0,column=0)
scroll = Scrollbar(root)
scroll.grid(row=0,column=1,sticky=N+S)
manager.config(yscrollcommand = scroll.set)
scroll.config(command=manager.yview)
manager.configure(scrollregion = manager.bbox("all"))
b = Button(root, text = "add entry", command = manager.add_entry)
b.grid(row=1,column=0)
root.mainloop()

You need to update the scrollregion of the canvas each time you add an entry:
if __name__ == "__main__":
root = Tk()
manager = SlowCH_Manager(root)
manager.grid(row=0,column=0)
scroll = Scrollbar(root)
scroll.grid(row=0,column=1,sticky=N+S)
manager.config(yscrollcommand = scroll.set)
scroll.config(command=manager.yview)
manager.configure(scrollregion = manager.bbox("all"))
def command():
manager.add_entry()
# update scrollregion
manager.configure(scrollregion = manager.bbox("all"))
b = Button(root, text = "add entry", command = command)
b.grid(row=1,column=0)
root.mainloop()

Related

is there a way to grid an extra button while running your program in tkinter correctly?

I'm making an mp3 player app and I want the user to be able to add playlists (which will be buttons in a grid system.
Like so.
However in this state when I'm trying to add a playlist button this happens:
The top buttons and the button i just added get squeezed off and the scrollbar is stuck (I can't use it)
I've tried refreshing by self.playlist_frame.update_idletasks() after running create_playlists() but it doesn't seem to change anything
this is my code so you can test it:
import os
import tkinter as tk
from tkinter import ttk
from PIL import Image, ImageTk
class MyApp:
def __init__(self):
self.root = tk.Tk()
self.width = self.root.winfo_screenwidth()
self.height = self.root.winfo_screenheight()
self.height = self.root.winfo_screenheight() - int(self.height / 13)
self.root.geometry(f'{self.width}x{self.height}')
self.root.title("Mp3")
self.c = '#14141D'
self.playlists_buttons_list = []
self.playlists = {}
self.helping_d = {}
self.main = ttk.Notebook(self.root)
self.playlists_tab = tk.Frame(self.main)
self.playlist_menu_frame = tk.Frame(self.playlists_tab, bg=self.c)
self.playlists_canvas = tk.Canvas(self.playlists_tab, bg=self.c)
self.playlist_frame = tk.Frame(self.playlists_canvas, bg=self.c)
self.playlists_scrollbar = ttk.Scrollbar(self.playlists_tab, orient='vertical',
command=self.playlists_canvas.yview)
self.add_playlist_win = tk.Toplevel(self.root)
self.add_playlists_button = tk.Button(self.playlist_frame)
self.default_img = Image.open('images/default.png').resize((75, 72))
self.default_img = ImageTk.PhotoImage(self.default_img)
self.add_img = Image.open('images/add.png').resize((50, 50))
self.add_img = ImageTk.PhotoImage(self.add_img)
self.widgets()
self.root.mainloop()
def widgets(self):
self.playlists_tab.place(height=self.height, width=self.width, x=0, y=0)
self.main.add(self.playlists_tab, text="Playlists")
self.main.pack(expand=1, fill="both")
self.playlist_frame = tk.Frame(self.playlists_canvas, bg=self.c)
self.playlists_canvas.create_window((0, 0), window=self.playlist_frame, anchor='center')
self.playlists_canvas.config(bg=self.c)
self.playlists_canvas.place(height=int(self.height / 1.428), width=self.width, x=0, y=int(self.height / 9))
self.add_playlists_button = tk.Button(self.playlists_canvas, image=self.add_img, bg=self.c, bd=0,
command=self.add_playlists)
self.add_playlists_button.place(x=1284, y=75)
self.playlists_scrollbar.pack(side='right', fill='y')
self.playlists_canvas.config(yscrollcommand=self.playlists_scrollbar.set)
self.playlists_canvas.bind('<Configure>', lambda e: self.playlists_canvas.configure(
scrollregion=self.playlists_canvas.bbox('all')))
if os.path.getsize('playlistsnames.txt') != 0:
lines = open('playlistsnames.txt', 'r', encoding='utf-8').read().splitlines()
for i in lines:
self.playlists[i] = []
self.create_playlists()
def create_playlists(self):
self.playlists_buttons_list = []
for i in range(len(self.playlists.keys())):
self.playlists_buttons_list.append(tk.Button(self.playlist_frame, bg=self.c,
text=' ' + list(self.playlists.keys())[i].split('!')[0],
fg='white', image=self.default_img, height=280, width=300))
row = 0
column = 0
for i in self.playlists_buttons_list:
if column > 3:
row += 1
column = 0
if column > 7:
row += 1
column = 0
i.grid(row=row, column=column)
column += 1
def get_name(self):
self.name_of_plst = self.plst_entry.get()
self.playlists[self.name_of_plst] = []
self.create_playlists()
with open('playlistsnames.txt', 'a', encoding='utf-8') as names_file:
names_file.write(self.name_of_plst + '!\n')
def add_playlists(self):
self.add_playlist_win = tk.Toplevel(self.root)
self.name_label = tk.Label(self.add_playlist_win, text='Name:', bg=self.c, fg='pink').pack()
self.plst_entry = tk.Entry(self.add_playlist_win)
self.plst_entry.pack()
self.confirm_btn = tk.Button(self.add_playlist_win, text='Confirm', bg=self.c, fg='pink',
command=self.get_name).pack()
self.add_playlist_win.mainloop()
MyApp()
I should also mention that because I store the playlist names in a file called playlistnames.txt when I rerun the program I can see all the playlist buttons plus the one I created before and things work just fine.
So what I want is making the grid update and work while running the app without having to rerun the app of course
My playlistsnames.txt file has this format:
rock!
metal!
chill!
rap!
jazz!
blues!
hard rock!
trap!
Any suggestions would be helpful!
Thanks in advance!

Need help understanding how to initialize classes in tkinter python

I'm creating a program that can trade currency using the binance API.
It works as intended (irrelevant code not included)
My problem is that I now want to make is possible to create several instances of the class Trade, in new pop up windows. I'm having trouble understanding how to achieve this in terms of creating new instances of the class Trade. Also I'm pretty sure that my use of self: self = Trade(top) dosen't make any sense (even though it works).
To sum it up:
I want to be able to click a button that starts a new instance of Trade(), so that I can use the methods in the class for two different trading routines at the same time in the same instance of the program. How?
I'll appreciate any form of help, including suggesting me to read up on something.
I'm sorry if im too noob.
Thx in advance.
class Trade(Frame):
stop_trading = False
amount_orders = 0
after_id = 0
def __init__(self, master=None):
Frame.__init__(self, master)
def change_orders(self):
if list_variable4.get() == 'TRUE':
if self.check_open_order() == False or self.amount_orders<2:
if self.delete_open_orders() == True and self.stop_trading != True:
self.create_orders()
...
def cron():
self.amount_orders += 1
if self.amount_orders > int(trade_cap_box.get(0.0, tk.END)):
message_window.insert(tk.END,'\nTrade Cycle Cap reached with {} trades'.format(self.amount_orders - 1))
cap_stop_trading()
if self.stop_trading != True:
message_window.insert(tk.END,'\nTrading Cycle Started{}'.format(self.amount_orders))
interval = int(rate_of_check_box.get(0.0, tk.END))
print('Trading!')
self.change_orders()
self.after_id = top.after(interval*1000*60, cron)
def start_trading():
self.amount_orders = 0
self.stop_trading = False
cron()
top = Tk()
top.geometry("600x500")
top.title('Trade Cron Job')
self = Trade(top)
message_window = Text(top, height=5, width=65)
message_window.place(x = 40,y = 10)
trading_symbol_box = Text(top, height=1, width=20)
trading_symbol_box.place(x = 200,y = 130)
default_trading_symbol = (self.config_data['configs']['symbol'])
if default_trading_symbol:
trading_symbol_box.insert(END, default_trading_symbol)
else:
trading_symbol_box.insert(END, "")
trading_symbol_labels = Label(top, text='Trading Symbol')
trading_symbol_labels.place(x = 40,y = 130)
start_value_box = Text(top, height=1, width=20)
start_value_box.place(x = 200,y = 160)
start_value_box.insert(END, 0)
start_value_labels = Label(top, text='Start Value To Progress From')
start_value_labels.place(x = 40,y = 160)
and so on...
top.mainloop()
You need to create an instance of Toplevel, then add the instance of Trade to that window.
def new_window():
window = Toplevel()
trade_frame = Trade(window)
trade_frame.pack(fill="both", expand=True)
...
new_window_button = Button(top, text="New Window", command=new_window)

save entry values for next programmstart tkinter

thanks a lot for your time. I'm currently stuck at the following point: I have developed a GUI with Tkinter with about 200 entries. (For simplification I have only included a small section below). But these 200 entries are seldom filled in at once. Normally 50 entries are filled in every start of the program. When the program is closed, these filled in values are deleted and have to be filled in again after the program is started again. Is there a way to prevent this?
I do not want to lose the values entered in jobNameA_entry and jobNameB_entry when closing the program.
Many thanks in any case.
import tkinter as tk
class Win1:
def __init__(self, master):
self.master = master
self.master.title("Gap Assessment")
self.topFrame = tk.Frame(self.master)
self.topFrame.grid(row=0, column=0, sticky='news', ipady = 5)
self.A_GapFrame = tk.Frame(self.master)
self.B_GapFrame = tk.Frame(self.master)
self.subframe_AGap()
self.subframe_BGap()
# Create a Tkinter variable
self.gapType = tk.StringVar(self.master)
# Dictionary with optionsverschwinden
self.choiceGap = ['AFrame','BFrame']
# self.choiceGap = sorted(self.choiceGap)
self.gapType.set('') # set the default option
self.ctngMenu = tk.OptionMenu(self.topFrame, self.gapType, *self.choiceGap, command=self.chioseGap_handle)
self.ctngMenu.grid(row = 1, column =2)
def chioseGap_handle(self, selected):
if selected == 'AFrame':
self.A_GapFrame.tkraise()
# self.subframe_AGap()
self.A_GapFrame.place(x=20, y=30, width = 210)
self.B_GapFrame.place_forget()
if selected == 'BFrame':
self.B_GapFrame.tkraise()
# self.subframe_BGap()
self.B_GapFrame.place(x=30, y=70, width = 210)
self.A_GapFrame.place_forget()
def subframe_AGap(self):
self.jobNameA_text = tk.StringVar()
self.jobNameA_entry = tk.Entry(self.A_GapFrame, textvariable = self.jobNameA_text)
self.jobNameA_entry.grid(row=1, column=0, sticky='news')
self.jobNameA_text = tk.StringVar()
self.jobNameA_entry = tk.Entry(self.A_GapFrame, textvariable = self.jobNameA_text)
def subframe_BGap(self):
self.jobNameB_text = tk.StringVar()
self.jobNameB_entry = tk.Entry(self.B_GapFrame, textvariable = self.jobNameB_text)
self.jobNameB_entry.grid(row=2, column=0, sticky='news')
self.jobNameB_text = tk.StringVar()
self.jobNameB_entry = tk.Entry(self.B_GapFrame, textvariable = self.jobNameB_text)
root = tk.Tk()
root.geometry("200x300+50+50")
app = Win1(root)
root.mainloop()

Passing the current class trouble

I thought I know the fundamentals of python, but this problem seems to prove that wrong.
Problem is, when I pass a class to a function, that function will not recognize the class that I passed, but instead just recognize that parent class.
This is the class.
from tkinter import *
from one_sample_t_test_dialog import One_T_Test_Dialog
from about_us_dialog import About_Us_Dialog
class Gui(Frame):
def __init__(self, master):
Frame.__init__(self, master, background="white")
self._master = master
# Main Window
frame = Frame(master, width = 800, height = 600)
self._master.title("Statistics Program")
# Menus
menu = Menu(master)
master.config(menu=menu)
# --Tests
test_menu = Menu(menu)
menu.add_cascade(label = "Tests", menu = test_menu)
# ----T-Tests
t_test_menu = Menu(test_menu)
test_menu.add_cascade(label = "T-Tests", menu = t_test_menu)
t_test_menu.add_command(label="One Sample t-test", command = self.one_sample_t_test)
t_test_menu.add_command(label="Two Sample t-test", command = self.two_sample_t_test)
t_test_menu.add_command(label="Paired t-test", command = self.about_us)
# --Help
help_menu = Menu(menu)
menu.add_cascade(label = "Help", menu = help_menu)
help_menu.add_command(label="About Us", command = self.about_us)
# Toolbar
# --t-test
toolbar = Frame(master)
l = Label(toolbar, text="Mean Comparison:")
l.pack(side=LEFT, padx = 5, pady = 5)
b=Button(toolbar, text = "One Sample t-test", command=self.one_sample_t_test)
b.pack(side=LEFT)
b=Button(toolbar, text = "Two Sample t-test", command=self.two_sample_t_test)
b.pack(side=LEFT)
b=Button(toolbar, text = "Paired t-test", command=self.two_sample_t_test)
b.pack(side=LEFT)
# --anova
l=Label(toolbar, text="ANOVA:")
l.pack(side=LEFT, padx = 5, pady = 5)
b=Button(toolbar, text = "One Way Anova", command=self.two_sample_t_test)
b.pack(side=LEFT)
# --Multiple-comparison Tests
toolbar_02 = Frame(master)
l=Label(toolbar_02, text="Multiple Mean Comparison:")
l.pack(side=LEFT, padx = 5, pady = 5)
b=Button(toolbar_02, text = "Tukey", command=self.two_sample_t_test)
b.pack(side=LEFT)
b=Button(toolbar_02, text = "Bonferroni", command=self.two_sample_t_test)
b.pack(side=LEFT)
toolbar.pack(fill=BOTH)
toolbar_02.pack(fill=BOTH)
# Spreadsheet.
self.canvas = canvas = Canvas(self._master)
self.canvas_frame = canvas_frame = Frame(canvas)
# Scrollbars
vbar=Scrollbar(self._master,orient=VERTICAL, command=self.canvas.yview)
hbar=Scrollbar(self._master,orient=HORIZONTAL, command=self.canvas.xview)
# Further configuration
canvas.configure(yscrollcommand=vbar.set, xscrollcommand=hbar.set)
# Initialize scrollbars
vbar.pack(side=RIGHT,fill=Y)
hbar.pack(side=BOTTOM,fill=X)
canvas.pack(side=LEFT, expand=True, fill="both")
canvas.create_window((4,4), window=canvas_frame, anchor="nw")
canvas_frame.bind("<Configure>", self.OnFrameConfigure)
self.grid()
#canvas_frame.pack()
self._master.geometry("800x600+50+50")
#self.pack(fill=BOTH, expand=1)
def get_master(self):
return self._master
def OnFrameConfigure(self, event):
'''Reset the scroll region to encompass the inner frame'''
self.canvas.configure(scrollregion=self.canvas.bbox("all"))
def about_us(self):
d = About_Us_Dialog(self._master)
root.wait_window(d.parent)
def grid(self):
"""
Make the grid here.
"""
grid_frame = self.canvas_frame
self.entry = []
for i in range(40):
self.entry.append([])
for i in range(len(self.entry)):
for j in range(80):
self.entry[i].append(Entry(grid_frame, width=10))
self.entry[i][j].grid(row=j, column=i)
# grid_frame.pack(padx=2, pady=2)
def one_sample_t_test(self):
d = One_T_Test_Dialog(self)
value = self._master.wait_window(d.parent)
# Check if an error occured.
result = None # We will store the result here.
if value is None:
return
else:
# perform the t-test here.
pass
# If we made it at this point, there's no error and
# the result have been acquired. We can now display
# the result.
def two_sample_t_test(self):
# Testing Ground
#print(self.get_variables())
#print(self.get_values(3))
pass
def get_variables(self):
"""
This method will return a dictionary of variable names and their corresponding
index, that is located in index zero of the double array. For instance,
self.entry[3][0] is a variable name, so is self.entry[5][0], and so on.
"""
variable_name_dict = {}
for i in range(len(self.entry)):
temp = self.entry[i][0].get()
if temp is not "":
variable_name_dict[i] = temp
return variable_name_dict
def get_values(self, variable_index):
"""
This method will return a list of values that is located under the variable.
Use this in conjunction with get_variables().
"""
values = []
if self.entry[variable_index][0] is not "": # Make sure that it's not empty.
for v in self.entry[variable_index]:
if v.get() is not "":
values.append(v.get())
# Since the first cell is in the column is always a variable name, we can
# pop the first element.
values.pop(0)
return values
root = Tk()
app = Gui(root)
root.mainloop()
This is the other class, with a method being called by the class above. the class above pass itself as an argument.
from tkinter import *
from tkinter import messagebox
import dialog
class One_T_Test_Dialog(dialog.Dialog):
def body(self, gui):
master = gui.get_master()
# Entry Labels.
Label(master, text="Mean:").grid(row=0)
Label(master, text="Standard Deviation:").grid(row=1)
Label(master, text="Sample Size:").grid(row=2)
Label(master, text="Sample Size:").grid(row=3)
Label(master, text="Test Value:").grid(row=4)
# Data entry class members.
# The for loop initialize the list as an entry list.
num_of_entry = 5
self.entry = [] #entry list
for i in range(num_of_entry):
self.entry.append(Entry(master))
# Data entry location initialization.
for i in range(num_of_entry):
self.entry[i].grid(row=i,column=1)
# Or, the user can just select a mean from the drop down list and
# enteryt the test value.
Label(master, text="Select Values Instead:").grid(column = 0, row=5)
self.dropdown_val = StringVar(master)
# initial value
self.dropdown_val.set('Select a values.')
choices = ['red', 'green', 'blue', 'yellow','white', 'magenta']
option = OptionMenu(master, self.dropdown_val, *choices).grid(column = 1, row=5)
button = Button(master, text="check value slected").grid(column=1, row=6)
# Further initialization.
# --At the Test Value, or null hypothesis, we want to have a default
# value. Assuming this is a 151/252 level course, the default value
# is always 0.
self.entry[4].insert(0, "0")
return self.entry[0] # initial focus
def apply(self):
# Collect the data first.
data_list = []
for e in self.entry:
data_list.append(e.get())
# Validate
for d in data_list:
# Make sure it's not empty.
# Make sure the value is float.
empty_flag = False
not_float_flag = False
if len(d) == 0:
empty_flag = True
if empty_flag is False:
try:
float(d)
except ValueError:
not_float_flag = True
if empty_flag is True or not_float_flag is True:
# Report an input error.
if empty_flag is True and not_float_flag is False:
messagebox.showerror("INPUT ERROR", "There's an empty input box.")
elif not_float_flag is True and empty_flag is False:
messagebox.showerror("INPUT ERROR", "Check your input. Make sure its a number.")
elif not_float_flag is True and empty_flag is True:
messagebox.showerror("INPUT ERROR", "There's an empty input box and non-numerical input.")
return None
# If everything went well, convert the validated data.
for i in range(len(data_list)):
data_list[i] = float(data_list[i])
return data_list
The problem is the line
master = gui.get_master()
in the second class gives an error because
AttributeError: 'Frame' object has no attribute 'get_master'
Frame being the parent of the class Gui.

Trouble creating 2D defaulted radiobutton

i'm trying to create a 2D grid of radiobuttons with default values. The grid may be as have as many as 256 rows but always 3 columns. I have researched much and tried many options and this is the best code I have for now. Obviously I am new to Python and Tkinter so any additional suggestions for solving my dilema (and code writing) are greatly appreciated. Also keep in mind that I will need to read back each row of radio buttons to determine which one was checked.
import Tkinter as tk
from Tkinter import *
class GUI(Frame):
def __init__(self, parent):
Frame.__init__(self, parent)
self.parent = parent
self.pack()
self.initUI()
def initUI(self):
# the 5Hz radio button should be selected as default
self.freqs=['1Hz','5Hz','10Hz']
self.numFreqs = len(self.freqs)
#val and var are set up to try to establish the defaults
#every 3 vals = 1 var therfore the middle val should = var
# val 0,1,2 = var 1 , val 3,4,5 = var 4 , val 6,7,8 = var 7
# this should allow the 5hx radiobuttonto be default selected
self.val = [0,1,2,3,4,5,6,7,8,9,10,11,12,13,14]
self.var=[1,4,7,10,13]
self.var[0] = IntVar()
self.var[1] = IntVar()
self.var[2] = IntVar()
self.var[3] = IntVar()
self.var[4] = IntVar()
self.cButtons = []
self.rButtons1 = []
self.rButtons2 = []
self.rButtons3 = []
self.textLbls = ['Choice 1', 'Choice 2', 'Choice 3','Choice 4','Choice 5']
#build enough values for 256 rows of 3 radiobuttons
#For var = [1,4,7,10... val = [0,1,2, 3,4,5, 6,7,8... so vars match vals on the 5hz radiobutton
#Can't do this since it creates the'many already selected bug'
#See http://stackoverflow.com/questions/5071559/tkinter-radio-button-initialization-bug
#for i in range(len(self.var)):
#self.var[i] = IntVar()
for i in range(len(self.textLbls)):
temp = self.val[(self.numFreqs*i)+1]
temp1 = self.var[i]
self.cButtons.append(Checkbutton(self, text=self.textLbls[i], onvalue=1, offvalue=0))
self.cButtons[i].grid(row=i, column=2, sticky = W)
Label(self, text=' Frequency:').grid(row=i, column=6)
#variable connects group of radios for slection/clear of group
#if value = variable this is default
self.rButtons1.append(Radiobutton(self, text=self.freqs[0], variable=self.var[i], value=self.val[(self.numFreqs*i)+0]))
self.rButtons1[i].grid(row=i, column=7, padx=5)
self.rButtons2.append(Radiobutton(self, text=self.freqs[1], variable=self.var[i], value=self.val[(self.numFreqs*i)+1]))
self.rButtons2[i].grid(row=i, column=8, padx=5)
self.rButtons3.append(Radiobutton(self, text=self.freqs[2], variable=self.var[i], value=self.val[(self.numFreqs*i)+2]))
self.rButtons3[i].grid(row=i, column=9, padx=5)
def main():
root = Tk()
app = GUI(root)
root.mainloop()
if __name__ == '__main__':
main()
Not entirely sure what problem you are looking for help with on this code, but I made a couple quick changes that should make it a bit more functional:
import tkinter as tk
from tkinter import *
class GUI(Frame):
def __init__(self, parent):
Frame.__init__(self, parent)
self.parent = parent
self.pack()
self.initUI()
def initUI(self):
# the 5Hz radio button should be selected as default
self.freqs=['1Hz','5Hz','10Hz']
self.numFreqs = len(self.freqs)
#val and var are set up to try to establish the defaults
#every 3 vals = 1 var therfore the middle val should = var
# val 0,1,2 = var 1 , val 3,4,5 = var 4 , val 6,7,8 = var 7
# this should allow the 5hz radiobutton to be default selected
self.val = [0,1,2,3,4,5,6,7,8,9,10,11,12,13,14]
#You only really need to hold on to a reference to the IntVars, not the
# entire widgets. Declaring each "var" individually is also unneccesary
self.checkButtonVars = []
self.radioButtonsVars = []
self.textLbls = ['Choice 1', 'Choice 2', 'Choice 3','Choice 4','Choice 5']
#(your comment block)
valueIter = iter(self.val) #This will let us read the values 3 by 3
for i,lbl in enumerate(self.textLbls): #enumerate is a nice way to avoid range(len(x))
tempVals = [next(valueIter) for x in range(3)] #get the next 3 values
#make a variable for the new CheckBox (and append it to our list)
self.checkButtonVars.append(IntVar(value=0))
#make a variable for the new RadioButton group (and append it to our list)
self.radioButtonsVars.append(IntVar(value=tempVals[1]))
#Make the checkboxes, radiobuttons and label for the line.
Checkbutton(self, text=lbl, variable=self.checkButtonVars[i]).grid(row=i, column=2, sticky = W)
Label(self, text=' Frequency:').grid(row=i, column=6)
Radiobutton(self, text=self.freqs[0], variable=self.radioButtonsVars[i], value=tempVals[0]).grid(row=i, column=7, padx=5)
Radiobutton(self, text=self.freqs[1], variable=self.radioButtonsVars[i], value=tempVals[1]).grid(row=i, column=8, padx=5)
Radiobutton(self, text=self.freqs[2], variable=self.radioButtonsVars[i], value=tempVals[2]).grid(row=i, column=9, padx=5)
#I added a button to retrieve the values, this is just as a demo.
self.printButton = Button(self,text='Return values',command=self.printVals)
self.printButton.grid(row=i+1,column=8)
def getRadioVals(self,*args):
#returns the values in the radio buttons as a list
return [x.get() for x in self.radioButtonsVars]
def getCheckVals(self,*args):
#returns the values in the checkboxes as a list
return [x.get() for x in self.checkButtonVars]
def printVals(self,*args):
print('Radio Buttons: %s' %(self.getRadioVals()))
print('Check Buttons: %s' %(self.getCheckVals()))
def main():
root = Tk()
app = GUI(root)
root.mainloop()
if __name__ == '__main__':
main()
If you could give a better description of specific problems you are having, it might be possible to address them.
Also, just as a note: trying to display 256 radiobuttons vertically is likely to cause you some problems. As far as I know, there is no way to create a scrolled Frame in standard tkinter, so your window will end up much taller than your screen.

Categories