質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.49%
Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

Tkinter

Tkinterは、GUIツールキットである“Tk”をPythonから利用できるようにした標準ライブラリである。

Q&A

解決済

1回答

8252閲覧

Python3 Tkinter テキストボックス入力の変化の取得

person

総合スコア223

Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

Tkinter

Tkinterは、GUIツールキットである“Tk”をPythonから利用できるようにした標準ライブラリである。

0グッド

0クリップ

投稿2020/04/30 13:41

編集2020/04/30 14:48

Tkinterでテキストボックスに文字を入力したときに、「テキストボックス内に変化が生じた」ことを取得する方法ってありますか?できれば、「変化が生じたときにどのような変化したか」も取得できるとありがたいです。

自分的には、キーバインドで
該当のテキストボックスにフォーカスが当たっていてかつ文字入力のキーボードが押された
度にテキストボックス内のデータを保存して比較をすればできないことはなさそうだと思いました。

ただ、この方法だとif文がめちゃくちゃ長くなりそうなので(aまたはbまたはcまたは・・・みたいな感じ)、もっと賢い方法があれば教えてください。
見落としているだけで、それを実現したbindとかがあるのかもしれませんが・・・。

テキストボックス入力後にボタンを押す
などといった、入力とは別のアクションを与えるのはなしでお願いします。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答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

teamikl

総合スコア8664

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.49%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問