2016-03-29 24 views
1

表示された画像からポイントを選択するインターフェースを開発しています。選択したポイントのリストがウィンドウの右側に表示されます。ユーザーがポイントをクリックするたびに、リストが更新されて新しいポイントが追加されます。リスト内のポイントは座標として表示され、座標の隣にはエントリウィジェットがあり、ユーザはその特定のポイントにテキストラベルを割り当てることができます。Tkinter:複数のエントリーウィジェットをリストに保存するときの問題

enter image description here

私は、ユーザーが選択するために起こっているどのように多くのポイントを知ることはできない、と私は右のポイントを選択した後やエンドユーザが名前のエントリを埋めるために起こっているかどうかを知ることができないので、すべての点を選択した後、ユーザーが「続行」ボタンを押した後に、入力ウィジェットからのテキストを読み込むことになります。

私がこれまで行ってきたことは、新しいポイントが追加されるたびに、つまり新しいEntryウィジェットが作成されるたびに、そのウィジェットがリストに保存されることです。これは、新しいポイントが追加されるたびに実行された機能である。しかし

def _read_data(self): 
    for t in self.entries: 
     self.labels.append(t.get()) 

、私はこれを実行すると、私が取得:

def _update_point_list(self): 
    self.dynamic_frame.pack_forget() 
    self.dynamic_frame.destroy() 
    self.dynamic_frame = Frame(self.Fpoints) 
    self.dynamic_frame.pack() 

    for coo, i in zip(self.dynamic_points, range(len(self.dynamic_points))): 
     L = Label(self.dynamic_frame, text=str([coo[0], coo[1]])) 
     T = Entry(self.dynamic_frame, width=15) 
     T.insert(INSERT, "Target name") 
     B = Button(
      self.dynamic_frame, 
      text='\xe2\x98\x92'.decode('utf8'), 
      command=lambda i=i: self._button_remove_point(i)) 
     L.grid(row=i + 1, column=1) 
     T.grid(row=i + 1, column=2) 
     B.grid(row=i + 1, column=3) 
     print T 
     self.entries.append(T) 

    if len(self.dynamic_points) > 0: 
     self.cont.configure(state=ACTIVE) 
     self.label.configure(
      text='\n    Selected points    \n') 
    else: 
     self.cont.configure(state=DISABLED) 
     self.label.configure(
      text='\n   No points selected   \n') 

は「CONTINUE」をボタンを押すと、次の関数を呼び出します次のエラーが:

Exception in Tkinter callback 
Traceback (most recent call last): 
File "/usr/lib/python2.7/lib-tk/Tkinter.py", line 1489, in __call__ 
return self.func(*args) 
File "/media/Fran/dataproc/timeseries/astrointerface.py", line 202, in _read_data 
self.labels.append(t.get()) 
File "/usr/lib/python2.7/lib-tk/Tkinter.py", line 2475, in get 
return self.tk.call(self._w, 'get') 
TclError: invalid command name ".140339446529128.140339400493320.140339400493896.140339400493608" 

私は 'self.labels' を印刷する場合、それは示しています

.140339446529128.140339400493320.140339400493896.140339400493608 

エントリの右側に別のボタンを追加してターゲット名を「ロード」するだけで、この問題を回避することができますが、これをワンクリックで行うことをお勧めします。しかし、私はコードで私のエラーを見ていないよ。

私はサイト上で同様の回答を見てきましたが、そのすべてがエントリウィジェットをリストに追加して使用していますので、ここで何が起こっているのか分かりません。

ありがとうございます。

+0

- > TclError:effbotのドキュメントから

無効なコマンド名を」.140339446529128.140339400493320.140339400493896.140339400493608" 一つだけのエントリで試してみてください、エントリの内容を削除_read_data()で同じウィジェットを再利用するだけです。 –

+0

[最小限の、完全で実証可能な例を作成する方法_](https://stackoverflow.com/help/mcve)をお読みください。 – martineau

+3

"無効なコマンド名" .xxxxx ""は通常、削除されたウィジェットでメソッドを呼び出そうとしていることを意味します。エントリウィジェットが破棄された後、このコードが実行されていますか? –

答えて

2

_update_point_listは、dynamic_frameを破壊し、最初のforループでは、作成したエントリをself.entriesに追加します。したがって、あなたの古いエントリ(動的フレームの子として破棄)はまだリストの中にあります。 self.entries = []self.dynamic_frame.destroy()の中に設定すると、_update_point_listが問題を解決するはずです。エントリIDのすべてが単一の文字列に参加してきた

destroy() [#] Destroys the widget. The widget is removed from the screen, and all resources associated with the widget are released.