Tkinter循环创建Radiobutton点击触发KeyError报错问题求解
问题原因
核心问题源于Python lambda函数的晚绑定特性:
- 循环中定义lambda时,不会立即保存
f、j的当前值,只有当lambda被触发(即点击单选按钮)时,才会去读取当前的f、j值。 - 待你点击单选按钮时,生成Radiobutton的循环已经执行完毕,
f、j已经变成了循环结束后的最终值,此时拼接出来的use_algo{f+j}的key超出了你预先定义的字典d的key范围(你只有use_algo0~use_algo3四个key),因此触发KeyError。
除此之外你的代码还有两处会引发报错的问题:
use_algo函数中self.entries.get()写法错误,self.entries是存储Entry控件的列表,需要通过下标取到对应Entry对象再调用get方法,即self.entries[i].get()。exec函数的返回值固定为None,你将arr = exec(...)无法拿到算法文件的执行结果;且你提供的算法文件中print array2是Python2语法,在Python3环境下运行会直接报错。
修复方案
1. 修复lambda绑定问题
给lambda添加默认参数,将当前循环的索引值绑定到参数上,修改生成Radiobutton的代码行即可:
lst_r["r{0}".format(f+j)] = Radiobutton( text = algorithms[f+j], var = v, value = f+j, height=2, width=30, indicator = 0, # 新增默认参数idx,绑定当前循环的f+j值 command = lambda idx=f+j: d[f'use_algo{idx}'](algorithms[idx]) )
2. 修复其他已知问题
修改use_algo函数中的错误写法:
def use_algo(algo_name): arr = [] for i in range(len(self.entries)): # 增加下标i取对应Entry控件 arr.append(self.entries[i].get()) # 执行算法文件,传入arr作为全局变量,执行结果存到local_vars local_vars = {'arr': arr} exec(open(f"/home/shirin/Desktop/Python Project/Algorithms/{algo_name}.py").read(), globals(), local_vars) # 从local_vars中拿算法执行后的结果 result = local_vars.get('array2', '无返回结果') label_output.configure(text = f'The array is {result}')
同时修改你的算法文件为Python3语法,示例:
def print_array(array): array2 = [] for i in array: array2.append(i) print(array2) return array2 # 执行后把结果赋值给变量,方便exec调用后取值 array2 = print_array(arr)
内容的提问来源于stack exchange,提问作者ShirinJZ
相关产品推荐
相关产品推荐

