Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/python-2.7/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何在python Tkinter中更新字典的值_Python_Python 2.7_Tkinter - Fatal编程技术网

如何在python Tkinter中更新字典的值

如何在python Tkinter中更新字典的值,python,python-2.7,tkinter,Python,Python 2.7,Tkinter,我有一个python tkinter应用程序,它有两个下拉列表和两个单选按钮 -几年来第一次下降 -这两个单选按钮是颜色和导航 -第三个下拉菜单是区域选择 现在,对于每个车型年款,都有不同的列和导航字典。根据您选择的是颜色还是导航,区域将发生变化。每个单选按钮在字典中都有自己的键。1表示颜色,2表示导航 我使用trace查找下拉列表和导航中的更改,如果第一个下拉列表更改,我调用函数callback1;如果单选按钮更改,我调用函数callback2 这是我的代码,我留下了足够的注释,以便让大家理

我有一个python tkinter应用程序,它有两个下拉列表和两个单选按钮

-几年来第一次下降

-这两个单选按钮是颜色和导航

-第三个下拉菜单是区域选择

现在,对于每个车型年款,都有不同的列和导航字典。根据您选择的是颜色还是导航,区域将发生变化。每个单选按钮在字典中都有自己的键。1表示颜色,2表示导航

我使用
trace
查找下拉列表和导航中的更改,如果第一个下拉列表更改,我调用函数callback1;如果单选按钮更改,我调用函数callback2

这是我的代码,我留下了足够的注释,以便让大家理解该程序:

from Tkinter import *


class App:

    def __init__(self, master):
        self.radioButtonVariable = IntVar()
        self.text = StringVar()
        frame = Frame(master, width=500, height=500)
        frame.pack_propagate(0) # set the flag to use the size
        frame.pack()

        #dictionaries for evey year [NOTE: 1 is for Color and 2 is for Navigation]

        self.dict17 = {1: ['China', 'Europe', 'North America'],
                       2: ['Australia', 'China', 'Europe']}

        self.dict16 = {1: ['China ', 'Europe ', 'North America '],
                       2: ['Australia ', 'China ', 'Germany']}

        self.dict15 = {1: ['China ', 'Europe-Russia ', 'North America '],
                       2: ['Australia ', 'New Zealand', 'England', 'Israel Region', 'Latin America Region', 'Middle East Region', 'North America Region', 'Philipines _Region', 'South American _Region', 'Turkey _Region']}

        self.dict14 = {1: ['China', 'Europe-Russia ', 'South America '],
                       2: ['Philipines Region', 'Turkey _Region']}

        self.dict = self.dict17.copy()    #set default dictionary to 2017

        #label for first dropdown
        self.MY_LABEL = Label(frame, text="Model Year:", anchor=W)
        self.MY_LABEL.grid(row=0, column=1)

        self.variable = StringVar(master)
        self.variable.set("2014")        #set default value to 2014 of dropdown

        #create the dropdown of model year
        self.w = OptionMenu(frame, self.variable, "2014", "2015", "2016", "2017")
        self.w.grid(row=0, column=2)

        self.variable.trace("w", self.callback1)   #check for changes in the variable and call callback function

        #radio buttons
        self.COL = Radiobutton(frame, text="Color", variable=self.radioButtonVariable, value=1)
        self.COL.grid(row=1, column=2)
        self.NAV = Radiobutton(frame, text="Navigation", variable=self.radioButtonVariable, value=2)
        self.NAV.grid(row=1, column=3)

        #region label
        self.REGION_LABEL = Label(frame, text="Region:", anchor=W)
        self.REGION_LABEL.grid(row=2,column=1)

        #check for changes in the radio buttons and call callback function 2
        self.radioButtonVariable.trace("w", self.callback2)

        self.variable2 = StringVar(master)

        #create second dropdown
        self.w2 = OptionMenu(frame, self.variable2, "")
        self.w2.grid(row=2, column=2)


    #this function clears the deault dictionary and copies a new one to it (SOMETHING IS WRONG HERE)
    def callback1(self, *args):
        module = self.variable.get()

        if module == "2017":
            self.dict.clear()
            self.dict = self.dict17.copy()
        elif module == "2016":
            self.dict.clear()
            self.dict = self.dict16.copy()
        elif module == "2015":
            self.dict.clear()
            self.dict == self.dict15.copy()
        else:
            self.dict.clear()
            self.dict == self.dict14.copy()

    #this function calls the second callback function and changes the dropdown the the new dictionary that is set
    def callback2(self, *args):
        countries = self.dict[self.radioButtonVariable.get()]
        self.variable2.set(countries[0])

        menu = self.w2["menu"]
        menu.delete(0, 'end')

        for country in countries:
            menu.add_command(label=country, command=lambda nation=country: self.variable2.set(nation))



root = Tk()
root.wm_title("application")
app = App(root)
root.mainloop()
错误

现在,如果下拉列表中的第一个选项是默认选项(2017年),那么该程序绝对可以正常运行。因此,如果在颜色和导航之间切换,区域中下拉列表的实际值将发生变化

然而,一旦你选择另一个年份,比如2015年,地区将不会改变,我会得到以下错误:

line 81, in callback2
    countries = self.dict[self.radioButtonVariable.get()]
KeyError: 1
我相信这是因为我正在清除字典并复制一本新字典,但新字典似乎没有被复制,因此找不到正确的键。所以问题出在函数回调2中


这个问题有什么解决方案吗?

由于区域取决于年份和单选按钮选择,因此您只需要一个回调,它使用这两个信息来填充区域下拉小部件。此回调方法也可以从
\uuuu init\uuuu()
调用,以在第一次选择词典时考虑到实际选择的年份,以防止出现错误,例如在代码中将“2014”放在下拉列表中,但复制2017年的词典

将每年的信息保存在按年份键入的字典中可以简化代码,并使其对数据的更改更加健壮

下面是代码的更新版本(也有更好的名称,并且在应用程序实例上没有不必要的属性):


嗨,非常感谢你的帮助。一个问题:您添加名称的if条件是什么。在哪里可以阅读更多关于它的内容来理解呢?Python文档中有一个非常简短的部分<代码>\uuuu名称\uuuu绑定到模块名称,但模块未导入但作为程序启动时除外。因此,如果您使用惯用的
if
条件导入模块,则不会发生任何事情-
main()
不会被调用,因为
\uuu name\uuu
等于模块名称。这对于在其他模块中使用部分模块的测试(手动或自动)来说是很好的,一些工具也希望模块可以导入而不会产生副作用。
#!/usr/bin/env python
from __future__ import absolute_import, division, print_function
import Tkinter as tk
from functools import partial

COLOR, NAVIGATION = 1, 2


class Application(object):

    def __init__(self, master):
        frame = tk.Frame(master)
        frame.pack()

        self.year2data = {
            2017: {
                COLOR: ['China', 'Europe', 'North America'],
                NAVIGATION: ['Australia', 'China', 'Europe'],
            },
            2016: {
                COLOR: ['China ', 'Europe ', 'North America '],
                NAVIGATION: ['Australia ', 'China ', 'Germany'],
            },
            2015: {
                COLOR: ['China ', 'Europe-Russia ', 'North America '],
                NAVIGATION: [
                    'Australia ', 'New Zealand', 'England', 'Israel Region',
                    'Latin America Region', 'Middle East Region',
                    'North America Region', 'Philipines _Region',
                    'South American _Region', 'Turkey _Region'
                ],
            },
            2014: {
                COLOR: ['China', 'Europe-Russia ', 'South America '],
                NAVIGATION: ['Philipines Region', 'Turkey _Region'],
            },
        }

        self.current_data = None

        tk.Label(frame, text='Model Year:', anchor=tk.E).grid(row=0, column=1)
        years = sorted(self.year2data.iterkeys())
        self.model_year_var = tk.IntVar(master)
        self.model_year_var.set(years[0])
        tk.OptionMenu(frame, self.model_year_var, *years).grid(
            row=0, column=2, columnspan=2
        )
        self.model_year_var.trace('w', self.update_region)

        self.color_or_navigation_var = tk.IntVar()
        tk.Radiobutton(
            frame, text='Color', variable=self.color_or_navigation_var, value=1
        ).grid(row=1, column=2)
        tk.Radiobutton(
            frame,
            text='Navigation',
            variable=self.color_or_navigation_var,
            value=2,
        ).grid(row=1, column=3)
        self.color_or_navigation_var.trace('w', self.update_region)

        tk.Label(frame, text='Region:', anchor=tk.E).grid(row=2, column=1)

        self.region_var = tk.StringVar(master)
        self.region_dropdown = tk.OptionMenu(frame, self.region_var, '')
        self.region_dropdown.grid(row=2, column=2, columnspan=2)

        self.update_region()

    def update_region(self, *_args):
        self.current_data = self.year2data[self.model_year_var.get()]
        color_or_navigation = self.color_or_navigation_var.get()
        if color_or_navigation != 0:
            regions = self.current_data[color_or_navigation]
            menu = self.region_dropdown['menu']
            menu.delete(0, tk.END)
            for region in regions:
                menu.add_command(
                    label=region, command=partial(self.region_var.set, region)
                )
            if self.region_var.get() not in regions:
                self.region_var.set(regions[0])


def main():
    root = tk.Tk()
    root.title('application')
    _ = Application(root)
    root.mainloop()


if __name__ == '__main__':
    main()