2012-01-17 46 views
-1

对于这条巨蟒2.7 Tkinter的代码,如果我输入“苹果”并点击“搜索”按钮,我应该从未知(“?”)重新设置字符串变量的选择和相关单选按钮来那些描述苹果(“脆皮”)和(“温和”),但我无法访问列表与我的if语句坐标列表。访问变量列表协调与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() 

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

我最初省略了这段代码的gui组件来简化事情,但显然只是让所有事情变得更加复杂,并且使我的代码看起来不稳定和奇怪。上面的代码应该给你一个很好的GUI窗口,但击中搜索按钮,什么也不做,但产生以下错误消息:

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

是否有一个列表理解或东西,我可以用它来解决这个,而不是重写我的代码?这是一个模拟的例子,试图解决我用一个更大的模块所遇到的问题。

回答

2

您的示例代码不是非常一致。例如,你定义一个StingVar对象,如果你愿意夫妇与Tkinter的部件,如Entry插件的对象,它将使意义:

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

考虑,我会ommit你的头部分和不喜欢它:

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。 这是唯一需要添加的两行(除了添加的以下行的标识)才能使您的代码正常工作。这不是优雅的,但也许你可以从中学到一些东西。

alternativly你也可以考虑doint这样的:

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]) 

如果您还有其他问题,只是发表评论,我将相应地更新我的答案。

+0

它看起来很奇怪,因为它是将字符串变量链接到单选按钮的较大代码的一部分。将发布整个事情。 – Jeff 2012-01-17 17:21:59

+0

谢谢。如果现在不够好,我会尽量满足功能。随着我的技能提高,毫无疑问,代码将不再那么快乐。 – Jeff 2012-01-17 22:30:46

4

您应该使用字典是:

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

编辑:又见standard library documentationofficial tutorial

编辑#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]) 

['?', '?']作为选项,如果水果不被你的程序是已知的。

+0

感谢您向我展示另一种方法来将我的元组作为字典进行编码,但打印'Apples'语句并不等同于设置字符串变量选项。我还很好奇如何表示变量元组坐标 – Jeff 2012-01-17 16:35:49

+0

我认为你的(唯一)问题是访问'纹理'和'气候'选项。嗯,好的。你可以用一个元组来访问'Apple'的特性:'list(filter(lambda x:x [0] =='Apple',fruits))',但是这不会比使用字典好。 – Gandaro 2012-01-17 16:49:22