使用if语句访问变量列表坐标



对于这个python 2.7 tkinter代码,如果我输入"Apple"并点击"Search"按钮,我应该将字符串变量选项和相关的单选按钮从未知("?")重置为描述苹果("Crunchy")和("Temperate")的单选按钮,但我在使用if语句访问列表坐标列表时遇到问题。

from Tkinter import*
class Fruit:
    def __init__(self, parent):
    # variables
    self.texture_option = StringVar()
    self.climate_option = StringVar()
    # layout
    self.myParent = parent
    self.main_frame = Frame(parent, background="light blue")
    self.main_frame.pack(expand=YES, fill=BOTH)
    texture_options = ["Soft", "Crunchy","?"]
    climate_options = ["Temperate", "Tropical","?"]
    self.texture_option.set("?")
    self.climate_option.set("?")
    self.texture_options_frame = Frame(self.main_frame, borderwidth=3, background="light blue")
    self.texture_options_frame.pack(side=TOP, expand=YES, anchor=W)
    Label(self.texture_options_frame, text="Texture:", relief=FLAT, font="bold", background="light blue").pack(side=LEFT,anchor=W)
    for option in texture_options:
        button = Radiobutton(self.texture_options_frame, text=str(option), indicatoron=0,
        value=option, padx=5, variable=self.texture_option, background="light blue")
        button.pack(side=LEFT)
    self.climate_options_frame = Frame(self.main_frame, borderwidth=3, background="light blue")
    self.climate_options_frame.pack(side=TOP, expand=YES, anchor=W)
    Label(self.climate_options_frame, text="Climate:", relief=FLAT, font="bold", background="light blue").pack(side=LEFT,anchor=W)
    for option in climate_options:
        button = Radiobutton(self.climate_options_frame, text=str(option), indicatoron=0,
        value=option, padx=5, variable=self.climate_option, background="light blue")
        button.pack(side=LEFT)
    #search button
    self.search_frame = Frame(self.main_frame, borderwidth=5, height=50, background="light blue")
    self.search_frame.pack(expand=NO)
    self.enter = Entry(self.search_frame, width=30)
    self.enter.pack(side=LEFT, expand=NO, padx=5, pady=5, ipadx=5, ipady=5)
    self.searchbutton = Button(self.search_frame, text="Search", foreground="white", background="blue",
    width=6, padx="2m", pady="1m")
    self.searchbutton.pack(side=LEFT, pady=5)
    self.searchbutton.bind("<Button-1>", self.searchbuttonclick)
    self.searchbutton.bind("<Return>", self.searchbuttonclick)

def searchbuttonclick(self,event):
    #fruit  texture  climate 
    fruit_bowl=[
    ('Apple', 'Crunchy','Temperate'),
    ('Orange', 'Soft','Tropical'),
    ('Pawpaw','Soft','Temperate')]
    if self.enter.get()==fruit_bowl[i][0]:
        self.texture_option.set(fruit_bowl[i][1])
        self.climate_option.set(fruit_bowl[i][2])

root = Tk()
root.title("Fruit Bowl")
fruit = Fruit(root)
root.mainloop()

我想说的是,如果在fruit_bowl中,任何给定行的入口窗口等于第0列,那么纹理选项设置为该行的第1列值,气候选项设置为第2列值,但在python中我该怎么说呢?

我最初提交了这段代码的gui组件来简化事情,但显然只是让一切变得更加复杂,让我的代码看起来断断续续。上面的代码应该会给你一个很好的GUI窗口,但点击搜索按钮只会生成以下错误消息:

Exception in Tkinter callback
Traceback (most recent call last):
File "C:Python25Liblib-tkTkinter.py", line 1403, in __call__
return self.func(*args)
File "F:Pythonfruit.py", line 59, in searchbuttonclick
if self.enter.get()==fruit_bowl[i][0]:
NameError: global name 'i' is not defined

有没有一个列表理解,或者我可以用什么来解决这个问题,而不是重写我的代码?这是一个模拟的例子,试图解决我在使用一个更大的模块时遇到的问题。

您应该为此使用字典:

fruits = {'Apple': ['Crunchy', 'Temperate'],
          'Orange': ['Soft', 'Tropical'],
          'Pawpaw': ['Soft', 'Temperate']}
print 'Apples are {}.'.format(' and '.join(fruits['Apple']))

编辑:另请参阅标准库文档和官方教程

编辑#2:当然你也可以设置这样的变量:

self.texture_option.set(fruits['Apple'][0])
self.climate_option.set(fruits['Apple'][1])

你也可以写这样的东西:

fruit = self.enter.get()
self.texture_option.set(fruits.get(fruit, ['?', '?'])[0])
self.climate_option.set(fruits.get(fruit, ['?', '?'])[0])

如果程序不知道水果,则使用['?', '?']作为选项。

您的示例代码不太一致。例如,您定义了一个StingVar对象,如果您将该对象与一个tkinter小部件(如Entry小部件:)耦合,这将是有意义的

self.entry_var = StringVar()
self.enter = Entry(root, width = 30, textvariable = self.entry_var)
selection = self.entry_var.get()

考虑到这一点,我会去掉你的头部,然后像一样做

self.enter = Entry(root, width=30)
self.enter.pack(side=LEFT, expand=NO)
#fruit  texture  climate 
fruit_bowl={'apple': ('Crunchy','Temperate'),
            'orange': ('Soft','Tropical'),
            'pawpaw': ('Soft','Temperate')}
selection = self.enter.get()
try:
   self.texture_option = fruit_bowl[selection.lower()][0]
   self.climate_option = fruit_bowl[selection.lower()][1]
   self.fruit_option = selection.capitalize()
except KeyError:
    print "%s not in fruit-bowl" % selection

如果你想保持你的代码原样,你必须做出如下的东西:

for fruit in fruit_bowl:
    i = fruit_bowl.index(fruit)
    if self.enter.get()==fruit_bowl[i][0]:
        self.texture_option.set(fruit_bowl[i][1])
        self.climate_option.set(fruit_bowl[i][2])

您在哪里定义了变量i?我看不到定义,也看不到python。为了纠正这种情况,我对fruit_bowl进行了迭代,并指定了值变量"i"的列表中实际元组索引的值。这是您必须添加的仅有的两行代码(除了下面几行添加的标识)。它不太优雅,但也许你可以从中学到一些东西。

或者你也可以考虑这样做:

for i in xrange(len(fruit_bowl)):
    if self.enter.get()==fruit_bowl[i][0]:
        self.texture_option.set(fruit_bowl[i][1])
        self.climate_option.set(fruit_bowl[i][2])

如果你有进一步的问题,请发表评论,我会相应地更新我的答案。

最新更新