【问题标题】:tkinter optionmenu keyerror on first 2 options前 2 个选项的 tkinter optionmenu keyerror
【发布时间】:2021-04-29 18:10:40
【问题描述】:

我有 2 个选项菜单。我们将调用 optionmenu1 plan_time 和 optionmenu2 week_options

第一个选项菜单 (plan_time) 设置周数。保存后,它会通过运行此函数来更新第二个选项菜单 (week_options),该函数会破坏 week_options 并重建它。

用于编写week_options 的新副本的代码与用于编写week_options 的第一个副本的代码相同。

week_clicked (week_options) 上有一个可以正常工作的跟踪。直到新的周数被保存并且小部件被销毁并重绘。然后由于某种原因,我新创建的列表的前 2 个选项不起作用。

currentweek = 4  # this is grabbed from config.ini but will just place a number for now.

def build_optionmenu():
    week_options.destroy()
    week_optionlist = {'Current Week':currentweek}
    add_optionlist = {"Week " + str(i):i for i in range(1,(plan_time_optionlist[plan_time_clicked.get()])+1)}
    week_optionlist.update(add_optionlist)
    week_clicked.set(currentweek)
    week_options = tk.OptionMenu(frame_settings_section2, week_clicked, *week_optionlist.keys())
    week_options.pack()

    print(week_optionlist)

plan_time_optionlist = {'Continuous':1}
add_optionlist = {str(i) + " Weeks":i for i in range(2,17)}
plan_time_optionlist.update(add_optionlist)
plan_time_clicked = StringVar()
plan_time_clicked.set(df_duration.get() + " Weeks")
plan_time_options = tk.OptionMenu(frame_settings_section2, plan_time_clicked, *plan_time_optionlist.keys())
plan_time_options.pack()
tk.Button(frame_settings_section2, text="<save>", command=update_optionmenus).pack()

我打印了这个列表,看看它是否看起来很有趣,但它看起来应该是这样的。

{'Current Week': 4, 'Week 1': 1, 'Week 2': 2, 'Week 3': 3, 'Week 4': 4, 'Week 5': 5,...}

所以我不明白为什么前 2 个选项“当前周”和“第 1 周” 给KeyError: 'Current Week'KeyError: 'Week 1' 当我从重新创建的下拉菜单中单击它们时。

【问题讨论】:

  • 我没有对函数做任何事情,现在第 1 周可以工作了。任何想法这可能是什么 LOL

标签: python tkinter trace optionmenu


【解决方案1】:

我不知道到底是什么问题,除了它与选项菜单使用的跟踪字符串变量有关。删除optionMenu时,跟踪行为有趣,而不是第二个选项菜单工作中的所有项目。

这是一个工作示例

将其复制并粘贴到 tkinter 窗口中

build optionmenu2 解释:

  • try: 删除 optionmenu2 和与之关联的跟踪。

  • 如果 optionmenu1 是“连续的”,则构建一个标签,而不是一个只有 1 个选项的无意义的 optionmenu。

  • 如果当前周(自程序启动以来)大于选择的周数,它将在选项菜单顶部显示错误(N),让用户知道我们当前处于比选择更高的周。

  • 构建 optionmenu2 并将默认设置为当前周或 optionmenu1 中选择的最后一周,以较大者为准。

每次在 optionmenu2 中选择一个选项时都会调用 load_week 我使用选择的选项来更改加载的内容。

    df_duration = StringVar()
    optionlist2_clicked = StringVar()
    df_duration.set('10')
    sys_weeks_growing = '4'
    
    label = tk.Label(self, text='how many weeks would you like the program to run')
    label.pack(padx=10, pady=10)
    
    def build_optionmenu2(*args):
        global optionmenu2, optionlist2
        try:
            optionmenu2.destroy()
            optionlist2_clicked.trace_vdelete('w', optionlist2_clicked.trace_week)
        except (NameError, AttributeError, KeyError):
            pass
        finally:
            if optionlist1[optionlist1_clicked.get()] == 1:
                tk.Label(self, text='Continuous:').pack(padx=10, pady=10)
                optionlist2_clicked.trace_week = optionlist2_clicked.trace_add('write', load_week)
                optionlist2_clicked.set('Week 1')
            elif int(optionlist1[optionlist1_clicked.get()]) >= 1:
                if int(optionlist1[optionlist1_clicked.get()]) >= int(sys_weeks_growing):
                    optionlist2 = {('Current(' + str(sys_weeks_growing) + ')'): sys_weeks_growing}
                else:
                    optionlist2 = {('Caution(' + str(sys_weeks_growing) + ')'): 1}
                new_optionlist = {"Week " + str(i): i for i in
                                  range(1, (optionlist1[optionlist1_clicked.get()]) + 1)}
                optionlist2.update(new_optionlist)
                optionmenu2 = tk.OptionMenu(self, optionlist2_clicked, *optionlist2.keys())
                optionmenu2.pack(padx=10, pady=10)
                optionlist2_clicked.trace_week = optionlist2_clicked.trace_add('write', load_week)
                if int(optionlist1[optionlist1_clicked.get()]) >= int(sys_weeks_growing):
                    optionlist2_clicked.set('Week ' + str(sys_weeks_growing))
                else:
                    optionlist2_clicked.set('Week ' + str(optionlist1[optionlist1_clicked.get()]))
                 
    def load_week(*args):
        print('data loaded...')
    
    optionlist1 = {'Continuous': 1}
    add_optionlist = {str(i) + " Weeks": i for i in range(2, 17)}
    optionlist1.update(add_optionlist)
    optionlist1_clicked = StringVar()
    optionlist1_clicked.set(df_duration.get() + " Weeks")
    optionmenu1 = tk.OptionMenu(self, optionlist1_clicked, *optionlist1.keys())
    optionmenu1.pack(padx=10, pady=10)
    optionlist1_clicked.trace_add('write', build_optionmenu2)   
    
    label = tk.Label(self, text='which week would you like to display').pack(padx=10, pady=10)
    
    build_optionmenu2()
        
    label = tk.Label(self, text='place widgets here that update when a week is selected from option menu 2')
    label.place(relx=.5, rely=.5, anchor='center')

【讨论】:

    猜你喜欢
    • 2013-10-08
    • 2019-07-04
    • 2016-05-10
    • 2021-03-09
    • 2015-09-23
    • 1970-01-01
    • 2022-08-04
    • 1970-01-01
    相关资源
    最近更新 更多