对于这个python 2.7 tkinter代码,如果我输入'Apple'并点击'Search'按钮,我应该将字符串变量选项和相关的radiobutton从未知(“?”)重置为描述苹果的那些(“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列值,而climate选项设置为该行的第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
是否有列表理解或我可以使用什么来解决这个而不是重写我的代码?这是一个模拟的例子,试图解决我在一个更大的模块中遇到的问题。
答案 0 :(得分:4)
你应该使用字典:
fruits = {'Apple': ['Crunchy', 'Temperate'],
'Orange': ['Soft', 'Tropical'],
'Pawpaw': ['Soft', 'Temperate']}
print 'Apples are {}.'.format(' and '.join(fruits['Apple']))
修改:另请参阅standard library documentation和official 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])
如果您的程序不知道水果,请选择['?', '?']
作为选项。
答案 1 :(得分:2)
你的示例代码不是很一致。例如,您定义了一个StingVar
对象,如果您将对象与像Entry
小部件这样的tkinter小部件耦合,这将是有意义的:
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])
如果您还有其他问题,请发表评论,我会相应更新我的答案。