Tkinterでテキストボックスに文字を入力したときに、「テキストボックス内に変化が生じた」ことを取得する方法ってありますか?できれば、「変化が生じたときにどのような変化したか」も取得できるとありがたいです。
自分的には、キーバインドで
該当のテキストボックスにフォーカスが当たっていてかつ文字入力のキーボードが押された
度にテキストボックス内のデータを保存して比較をすればできないことはなさそうだと思いました。
ただ、この方法だとif文がめちゃくちゃ長くなりそうなので(aまたはbまたはcまたは・・・みたいな感じ)、もっと賢い方法があれば教えてください。
見落としているだけで、それを実現したbindとかがあるのかもしれませんが・・・。
テキストボックス入力後にボタンを押す
などといった、入力とは別のアクションを与えるのはなしでお願いします。
気になる質問をクリップする
クリップした質問は、後からいつでもMYページで確認できます。
またクリップした質問に回答があった際、通知やメールを受け取ることができます。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
回答1件
0
ベストアンサー
「テキストボックス内に変化が生じた
簡単な方法では
python
1import tkinter as tk 2 3def on_modified(e): 4 print(e) 5 e.widget.edit_modified(False) # フラグをオフにする事で、毎回呼ばれるようにする。 6 7root = tk.Tk() 8text = tk.Text(root) 9text.bind("<<Modified>>", on_modified) 10text.pack() 11root.mainloop()
見落としているだけで、それを実現したbindとかがあるのかもしれませんが・・・。
用途次第ですが、<KeyPress>
では不十分ですか?
「変化が生じたときにどのような変化したか」
テキストボックス自身の機能としては、標準では提供されていませんが、
ユーザ自身で出来る拡張で <<TextModifiled>>
仮想イベントを追加する方法があるようです。
以下は、tk.Text と ScrolledText に適応させた例
python
1# 参考URL 2 3# Text の変化を補足し仮想イベントを起こす方法 4# https://stackoverflow.com/questions/40617515/python-tkinter-text-modified-callback 5 6# 上記の CustomText クラスで、ペースト時にエラー 7# https://stackoverflow.com/questions/53417668/getting-a-tkinter-tclerror-when-i-try-to-cut-and-paste-in-a-custom-tkinter-text 8 9# event_generate でのパラメータの受け渡し => tkinter では未対応 10# https://bugs.python.org/issue3405 11 12 13import tkinter as tk 14from tkinter.scrolledtext import ScrolledText 15 16class TextModifiedMixin: 17 def __init__(self): 18 self.__orig = self._w + "_orig" 19 self.tk.call("rename", self._w, self.__orig) 20 self.tk.createcommand(self._w, self.__proxy) 21 22 def __proxy(self, command, *args): 23 cmd = (self.__orig, command) + args 24 try: 25 result = self.tk.call(cmd) 26 except tk.TclError: 27 # XXX: Copy&Paste操作等での例外を無視 28 return None 29 """ 30 # イベントの種類を細分化する場合 31 if command == "insert": 32 self.event_generate("<<TextInserted>>") 33 elif command == "delete": 34 self.event_generate("<<TextDeleted>>") 35 elif command == "replace": 36 self.event_generate("<<TextReplaced>>") 37 else: 38 pass 39 """ 40 if command in ("insert", "delete", "replace"): 41 self.event_generate("<<TextModified>>", data=command) 42 else: 43 pass 44 45 return result 46 47 48class CustomText(tk.Text, TextModifiedMixin): 49 def __init__(self, master, **kw): 50 super().__init__(master, **kw) 51 TextModifiedMixin.__init__(self) 52 53class CustomScrolledText(ScrolledText, TextModifiedMixin): 54 def __init__(self, master, **kw): 55 super().__init__(master, **kw) 56 TextModifiedMixin.__init__(self) 57 58 59if __name__ == "__main__": 60 root = tk.Tk() 61 textBox = CustomScrolledText(root) 62 textBox.pack(fill=tk.BOTH, expand=1) 63 64 def on_text_modified(e): 65 print(e) 66 67 textBox.bind("<<TextModified>>", on_text_modified) 68 69 ## event_generate での data=command を受け取りたい場合 70 # cmd = root.register(on_text_modified) 71 # root.tk.call("bind", textBox, "<<TextModified>>", cmd) 72 73 root.mainloop()
注意点: ペースト時のエラーのみ確認しましたが、他にもエラーになるケースがあるかもしれません。
デバッグの際はソース内注釈 (XXX) の箇所で例外を表示させる等の工夫してください。
投稿2020/04/30 15:52
総合スコア8760
あなたの回答
tips
太字
斜体
打ち消し線
見出し
引用テキストの挿入
コードの挿入
リンクの挿入
リストの挿入
番号リストの挿入
表の挿入
水平線の挿入
プレビュー
質問の解決につながる回答をしましょう。 サンプルコードなど、より具体的な説明があると質問者の理解の助けになります。 また、読む側のことを考えた、分かりやすい文章を心がけましょう。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。