Tkinter第二个OptionMenu命令无响应问题求助
问题描述
我创建了两个OptionMenu组件,第一个用于选择制造商,其绑定的命令会清空第二个OptionMenu的选项并添加与所选制造商对应的选项。但目前第二个OptionMenu绑定的命令无法触发,删除/注释第一个OptionMenu后,第二个就能正常工作。请问这是什么原因?
代码片段
self.cells_menu = tk.OptionMenu(self.local_master, self.selected_cell, *[c.full_name() for c in available_cells.values() if len(c.performed_tests)>0], command=lambda x: self.on_cell_select(x)) self.cells_menu.config(width=40, anchor="w") self.cells_menu.grid(row=1, column=0, sticky="W", columnspan=2) # (...) self.selected_test = tk.StringVar(self.local_master) self.test_menu = tk.OptionMenu(self.local_master, self.selected_test, *(None, None), command=lambda x: print(self.selected_test, x)) self.test_menu.config(width=40, anchor="w") self.test_menu.grid(row=3, column=0, sticky="W", columnspan=2) # (...) def on_cell_select(self, cell_name: str): self.selected_cell.set(cell_name) new_cell = self.available_cells[cell_name] self.update_test_list(new_cell, self.test_menu, self.selected_test) def on_test_select(self, cell_name: str): print(cell_name) curr_cell = self.available_cells[cell_name] print(curr_cell) def update_test_list(self, new_cell: Cell, menu_to_update: tk.OptionMenu, assign_varstring: tk.StringVar): self.selected_test.set('') menu_to_update["menu"].delete(0, "end") for test in new_cell.performed_tests: menu_to_update["menu"].add_command(label=test, command=tk._setit(assign_varstring, test))
原因分析
问题出在update_test_list方法的菜单选项添加逻辑上:
- 当你用
menu_to_update["menu"].add_command动态添加选项时,仅通过tk._setit实现了选中值到StringVar的赋值,但没有保留第二个OptionMenu原本绑定的command回调。 tk._setit生成的回调只会完成变量赋值,不会触发你创建test_menu时指定的command=lambda x: print(self.selected_test, x)。第一个OptionMenu的更新操作覆盖了原菜单选项,直接导致原命令绑定丢失。
另外,on_cell_select里的self.selected_cell.set(cell_name)是多余的——OptionMenu的command参数会自动将选中值同步到对应的StringVar,无需手动设置。
解决方案
修改update_test_list方法,在添加新选项时,把原command回调和tk._setit的赋值逻辑串联起来:
def update_test_list(self, new_cell: Cell, menu_to_update: tk.OptionMenu, assign_varstring: tk.StringVar): self.selected_test.set('') menu_to_update["menu"].delete(0, "end") # 获取test_menu原本绑定的command回调 original_command = menu_to_update.cget("command") for test in new_cell.performed_tests: # 自定义回调:先完成变量赋值,再触发原command def callback(val=test): # 执行tk._setit的变量赋值逻辑 tk._setit(assign_varstring, val)() # 如果原command存在,触发它 if original_command: original_command(val) menu_to_update["menu"].add_command(label=test, command=callback)
同时删除on_cell_select里多余的self.selected_cell.set(cell_name)代码。
内容的提问来源于stack exchange,提问作者Paweł Pietraszko
相关产品推荐
相关产品推荐

