我有一个函数通过grid()创建条目,如下所示:(用函数替换while循环,这应该只显示它后面的内容)
from Tkinter import *
root = Tk()
index=0
while index < 10:
col0 = Text(root,width=20, height=1, bg='white')
col0.grid(row=index,column=0)
col0.insert('0.0',"name")
col1 = Text(root,width=20, height=1, bg='white')
col1.grid(row=index,column=1)
col1.insert('0.0',"attribute #1")
col2 = Text(root,width=20, height=1, bg='white')
col2.grid(row=index,column=2)
col2.insert('0.0',"attribute #2")
col3 = Text(root,width=20, height=1, bg='white')
col3.grid(row=index,column=3)
col3.insert('0.0',"counter")
index+=1
root.mainloop()
所以在特殊事件中调用该函数并创建一个新条目(一个新行)。但是如果已经有这个事件的条目,我只想增加计数器。
事件名及其分类(索引)保存在字典中,所以我确实有行和列,但我现在如何实际访问col3?
我计划通过col3.get()获取计数器,但在每一行都称为col3,那我怎么指定呢?
是否可以将col0,col1,col2等放入一种结构(如字典),所以通过col0 [name] .insert()...(名称是唯一的)访问它们?我尝试了但是没有用(这并不意味着我不可能希望,我只是对python很新)
有没有人对我的问题有任何建议或解决方案?
答案 0 :(得分:2)
你的字典想法很好。我在这里提出了一个简单的实现...(类是在函数调用之间保持数据持久性的最佳方法。)
在此示例中,您可以通过app.ObjGrid[(row,col)]
访问文本小部件,或者如果您是通过方法执行此操作,则可以通过self.ObjGrid[(row,col)]
访问它。
import Tkinter as tk
class TextGrid(tk.Frame):
def __init__(self,master):
tk.Frame.__init__(self,master)
self.ObjGrid={}
self.index=1
for i in xrange(10):
self.addRow()
def addRow(self,index=None):
"""
add a row of widgets at row=<index>. If index is omitted, add the next row
If index is on the grid already, prints "Increment counter?" since I don't
know what you mean by that
"""
if(index is None):
index=self.index+1
self.index+=1
if (index,0) in self.ObjGrid:
print "Increment counter?" #probably replace this code...
return
self.ObjGrid[(index,0)] = col0 = tk.Text(self,width=20, height=1, bg='white')
col0.grid(row=index,column=0)
col0.insert('0.0',"name")
self.ObjGrid[(index,1)] = col1 = tk.Text(self,width=20, height=1, bg='white')
col1.grid(row=index,column=1)
col1.insert('0.0',"attribute #1")
self.ObjGrid[(index,2)] = col2 = tk.Text(self,width=20, height=1, bg='white')
col2.grid(row=index,column=2)
col2.insert('0.0',"attribute #2")
self.ObjGrid[(index,3)] = col3 = tk.Text(self,width=20, height=1, bg='white')
col3.grid(row=index,column=3)
col3.insert('0.0',"counter")
if __name__ == "__main__":
root=tk.Tk()
app=TextGrid(root)
app.grid(row=0,column=0)
app.addRow(3) #Shouldn't do anything
app.addRow() #Should add another row to the end.
print(type(app.ObjGrid[(2,3)])) #tkinter text widget.
root.mainloop()
作为关于风格的说明......
from XXX import *
通常不赞成。
import XXX as short_name_that_is_easy_to_remember
通常是优选的。此外,当在Tkinter做东西时,我发现从类开始总是最容易的。构建小部件。将窗口小部件更改为应用程序是微不足道的,但将应用程序更改为窗口小部件几乎是不可能的。构建窗口小部件的最简单方法是从Frame
继承,然后将其他窗口小部件打包到该框架上,如上所示。
答案 1 :(得分:1)
您需要保存对您创建的所有Text小部件的引用:
colHeaders = ["name", "attribute #1", "attribute #2", "counter"]
myTextWidgets = []
for index in range(10):
subList = []
for i, header in enumerate(colHeaders):
text = Text(root,width=20, height=1, bg='white')
text.grid(row=index,column=i)
text.insert('0.0',header)
subList.append(text)
myTextWidgets.append(subList)
这将允许您通过它的行/列访问每个小部件:
myTextWidgets[0][1].config(bg="purple")
您可以轻松地将新行添加到此结构中,如下所示:
subList = []
for i, header in enumerate(colHeaders):
text = Text(root,width=20, height=1, bg='white')
text.grid(row=len(myTextWidgets),column=i)
text.insert('0.0', header)
subList.append(text)
myTextWidgets.append(subList)
使用这种结构,名称不是唯一的,而是每个单元格的位置。
答案 2 :(得分:1)
不仅有可能,我认为这样的情况更可取。这是一个简单的方法:
attr_names = ['name', 'attribute #1', 'attribute #2', 'counter']
def make_text_field(row, col, attr_name):
text = Text(root, width=20, height=1, bg='white')
text.grid(row=row, column=col)
text.insert('0.0', attr_name)
text_fields = {}
for row, col in itertools.product(xrange(10), xrange(4)):
text_fields[row, col] = make_text_field(row, col, attr_names[col])
这会将每个字段分别存储在text_fields
中,并以(row, col)
元组作为键。您还可以创建列表列表;既然你想访问整列,你可能更喜欢这样。您可以预先分配列表并使用上面的product
,但为简单起见,这是另一种方法:
list_of_cols = list()
for col in xrange(4):
col = list()
list_of_cols.append(col)
for row in xrange(10):
col.append(make_text_field(row, col, attr_names[col]))