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

あなたの辞書のアイデアは良いです。ここで必要最低限​​の実装を考え出しました...(クラスは、関数呼び出し間でデータを永続的に保つための最良の方法です)。

この例では、テキストウィジェットにアクセスするか、メソッドから実行している場合は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

作成するすべてのテキストウィジェットへの参照を保存する必要があります。

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

可能であるだけでなく、このような状況に適していると思います。簡単なアプローチの 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 に答える