I'm creating multiple radiobuttons in a loop and assigning a function with one argument to them by lambda(These functions are also created using loops and dictionary), but when I press on on of the radiobuttons I get this error:
Exception in Tkinter callback
Traceback (most recent call last):
File "/home/shirin/anaconda3/lib/python3.8/tkinter/__init__.py", line 1892, in __call__
return self.func(*args)
File "/tmp/ipykernel_7981/822586079.py", line 99, in <lambda>
lst_r["r{0}".format(f j)] = Radiobutton(text = algorithms[f j], var = v, value = f j, height=2, width=30, indicator = 0, command = lambda: d['use_algo' str(f j)](algorithms[f j]))
KeyError: 'use_algo35'
For the algorithm files I created 4 .py files containing the following code:
def print_array(array):
array2 = []
for i in array:
array2.append(i)
print array2
array = arr
print_array(array)
And here is a minimal code like mine; Running this code it returns KeyError: 'use_algo5':
from tkinter import *
root = Tk()
row_num = 0
font = ('Verdana', 10)
algorithms = ['algorithm1','algorithm2','algorithm3','algorithm4']
def enter():
try:
class entries:
def __init__(self, root):
self.variables = []
n = 4
for i in range(n):
self.variables.append(StringVar())
self.labels = []
self.entries = []
c, d, e = 0,0,0
for ii in range(int(n/4)):
for jj in range(4):
num = c (jj 1)
self.labels.append(Label(root , text = num))
self.labels[-1].grid(padx=0, pady=0, row=ii d 1, column=jj)
self.entries.append(Entry(root, font = font, textvariable =self.variables[c (jj)], width = 30))
self.entries[-1].grid(padx=0, pady=0, row=ii d 2, column=jj)
d =2
c =4
e = ii 1 d
label_algo = Label(font = font, text = 'Choose an algorithm:')
label_algo.grid(row = int(n/4) e 2 , column = 0, padx = 29, pady = 15)
row_num = int(n/4) e 2
def use_algo(algo_name): ### radio button functions:
arr = []
for i in range(int(len(self.entries))):
arr.append(self.entries.get())
arr = exec(open("/home/shirin/Desktop/Python Project/Algorithms/" algo_name ".py").read())
label_output.configure(text = 'The array is {}'.format(arr))
d = {f'use_algo{k}': partial(use_algo, algo_name=algorithms[k]) for k in range(int(len(algorithms)))}
v = IntVar()
lst_r = {}
f = 0
for i in range(int(len(algorithms)/2)): ### making radio buttons:
for j in range(2):
lst_r["r{0}".format(f j)] = Radiobutton(text = algorithms[f j], var = v, value = f j, height=2, width=30, indicator = 0, command = lambda: d['use_algo' str(f j)](algorithms[f j]))
lst_r["r{0}".format(f j)].grid(row=row_num 1 i, column=j)
f =2
label_output = Label(font = font)
label_output.grid(row = row_num 1 int(len(algorithms)/4) 1 , column = 0, padx = 29, pady = 15)
T = entries(root)
except:
pass
label_num = Label(font = font, text = 'Press enter button')
label_num.grid(row = 0 , column = 0, padx = 30, pady = 15)
button_enter = Button(text = 'Enter', command = enter, width = 20)
button_enter.grid(row = 0 , column = 2, padx = 30)
root.mainloop()
CodePudding user response:
When the lambda is executed by clicking one of the radiobuttons, f j
is 5 because f
is 4 and j
is 1 after the for loop of creating those radiobuttons.
Also it is usually use partial()
directly in command
option as below:
command=partial(use_algo, algorithms[f j])
Then d
is not necessary at all.
Note that the for loop inside use_algo()
is not necessary because arr
is overwritten by:
arr = exec(open("/home/shirin/Desktop/Python Project/Algorithms/" algo_name ".py").read())