1

我有一个通过 grid() 创建条目的函数,如下所示:(用函数替换 while-loop,这应该只是向您展示它稍后的样子)

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 还很陌生)

有人对我的问题有任何建议或解决方案吗?

4

3 回答 3

2

你的字典想法很好。我在这里提出了一个简单的实现......(类是在函数调用之间保持数据持久性的最佳方式。)

在此示例中,您的 Text 小部件可以通过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然后将其他小部件打包到该框架上。

于 2012-06-15T14:23:31.983 回答
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)

使用这种结构,唯一的不是名称,而是每个单元格的位置

于 2012-06-15T14:25:03.147 回答
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]))
于 2012-06-15T14:25:59.417 回答