回答編集履歴

1

trace版 追記

2020/06/11 13:09

投稿

hope_mucci
hope_mucci

スコア4447

test CHANGED
@@ -159,3 +159,77 @@
159
159
  app.mainloop()
160
160
 
161
161
  ```
162
+
163
+
164
+
165
+ ### 追記
166
+
167
+ コメントの内容を受けてtrace版を作ってみました。
168
+
169
+ 新しいコンポーネントクラスは作らなくてもよくなります。
170
+
171
+ ただしbindのような柔軟なイベント処理ができない(trace発生元のStringVarはわかるがそこからバインドされているコンポーネントをたどるのは難しい)ので多数のコンポーネントが相手になるとソースがこんがらかりそうです。監視先が1つ2つだったら楽そうです。
172
+
173
+ ```python
174
+
175
+ import tkinter as tk
176
+
177
+
178
+
179
+ class SampleApp(tk.Tk):
180
+
181
+
182
+
183
+ def __init__(self, *args, **kwargs):
184
+
185
+ tk.Tk.__init__(self, *args, **kwargs)
186
+
187
+ # StringVarとEntryはコールバック内で参照するためインスタンス変数にする
188
+
189
+ self.sv1 = tk.StringVar()
190
+
191
+ self.sv1.trace("w",self.var_changed) # sv1に書き込みされるとvar_chagedがコールバック
192
+
193
+
194
+
195
+ self.e1 = tk.Entry(self, textvariable = self.sv1) # textvariableとsv1をバインド
196
+
197
+ e2 = tk.Entry(self)
198
+
199
+
200
+
201
+ e2.insert(0,"2")
202
+
203
+
204
+
205
+ self.e1.pack()
206
+
207
+ e2.pack()
208
+
209
+ # argsにはtrace発生元のVarの_nameが入っている
210
+
211
+ # StringVarはargsから探せるが発生元のエレメントを探すのは大変
212
+
213
+ # なのでイベント発生元はハードコーディング
214
+
215
+ def var_changed(self, *args):
216
+
217
+ s = self.sv1.get()
218
+
219
+ if len(s) == 0:
220
+
221
+ return
222
+
223
+ if s[-1] == "\n":
224
+
225
+ self.e1.tk_focusNext().focus_set()
226
+
227
+
228
+
229
+ if __name__ == "__main__":
230
+
231
+ app = SampleApp()
232
+
233
+ app.mainloop()
234
+
235
+ ```