使用循环创建Tkinter OptionMenu时选择选项触发报错问题
我帮你看看这个问题——你的OptionMenu能正常显示选项,但选择时触发报错,核心问题出在你用exec()来创建和传递StringVar变量的方式上,咱们一步步理清楚:
错误原因分析
exec()函数是用来执行字符串形式的代码,但它不会返回任何值(默认返回None)。你在创建OptionMenu时用exec('variable=self.tkvar_'+str(i))作为参数,实际上传递给OptionMenu的是None,而不是你想要的StringVar对象。这就导致OptionMenu没有绑定有效的变量,选择选项时自然会触发报错。- 另外,直接在类里使用全局的
root对象虽然能运行,但不是规范的写法,容易引发作用域问题。
修正后的代码
我们可以用字典来存储每个分类对应的StringVar变量,完全替代exec()的动态变量名方案,代码更清晰也更安全:
import tkinter as tk from tkinter import Tk class Example: def __init__(self, root): # 存储分类及对应关键词的字典 self.categorykeywords = { "Category 1": ["Keyword 1", "Keyword 2", "Keyword 3"], "Category 2": ["Keyword A", "Keyword B", "Keyword C"], "Category 3": ["Another Keyword"] } # 按分类名存储OptionMenu的字典 btn_dict = {} # 存储每个分类对应的StringVar变量,替代原来的动态变量名 self.dropdownreference = {} columncounter = 0 for category in self.categorykeywords: # 直接为每个分类创建StringVar并存储到字典中 self.dropdownreference[category] = tk.StringVar(root) # 设置默认显示的选项(可选,这里设为第一个关键词) self.dropdownreference[category].set(self.categorykeywords[category][0]) # 用字典里的StringVar创建OptionMenu btn_dict[category] = tk.OptionMenu( root, self.dropdownreference[category], *self.categorykeywords[category] ) btn_dict[category].grid(row=0, column=columncounter, padx=1, pady=1) columncounter += 1 if __name__ == "__main__": root = Tk() my_gui = Example(root) root.mainloop()
关键修改点说明
- 用字典替代exec动态变量:
self.dropdownreference字典直接存储每个分类对应的StringVar对象,不需要用exec()生成tkvar_1这类动态变量名,避免了作用域和返回值的问题。 - 正确传递StringVar给OptionMenu:创建OptionMenu时直接使用
self.dropdownreference[category]作为绑定变量,确保OptionMenu能正确关联到有效的StringVar对象。 - 规范传递root参数:将
root作为参数传给Example类的构造函数,不再依赖全局变量,代码更健壮。 - 可选:设置默认选项:用
set()方法给每个OptionMenu设置默认显示的选项,提升用户体验。
这样修改后,你选择OptionMenu的选项时就不会再报错,还能通过self.dropdownreference[分类名].get()轻松获取当前选中的关键词。
内容的提问来源于stack exchange,提问作者Erico9001
相关产品推荐
相关产品推荐

