Tk のほとんどのイベントと同様に、ハンドラーは、イベントが組み込みバインディングによって処理された後ではなく、処理される前に<Key>
起動されます。これにより、たとえば、通常の処理が行われないようにしたり、処理内容を変更したりできます。
ただし、これは、まだ更新されていないため、新しい値にアクセスできないことを意味します ( を介してStringVar
、または を呼び出すだけで)。entry.get()
を使用している場合は、「変更済み」フラグが変更された後にText
発生する仮想イベントがあります。<<Modified>>
そのフラグを別の目的で使用していないと仮定すると (たとえば、テキスト エディターでは、「保存ボタンを有効にする」という意味で使用したい場合があります)、それを使用して、まさに必要なことを行うことができます。
def count(self, event=None):
if not self.post_tweet.edit_modified():
return
self.post_tweet.edit_modified(False)
self.x = len(self.post_tweet.get(1.0, END))
self.char_count.set(str(140 - self.x))
# ...
self.post_tweet.bind("<<Modified>>", self.count)
通常、このようなものが必要な場合は、Entry
ではなく が必要ですText
。これは、これを行うためのはるかに優れた方法である検証を提供します。Tkinter の基本を超えたすべてのものと同様に、Tcl/Tk ドキュメントを読まずにこれを理解する方法はありません (これが、Tkinter ドキュメントがそれらにリンクしている理由です)。実際、Tk のドキュメントでさえ検証についてはあまり詳しく説明していません。しかし、これがどのように機能するかです:
def count(self, new_text):
self.x = len(new_text)
self.char_count.set(str(140 - self.x))
return True
# ...
self.vcmd = self.master.register(self.count)
self.post_tweet = Edit(self.master, validate='key',
validatecommand=(self.vcmd, '%P'))
はvalidatecommand
、関数に渡す 0 個以上の引数のリストを取ることができます。引数は、%P
許可した場合にエントリが持つ新しい値を取得します。詳細についてVALIDATION
は、エントリのマンページを参照してください。
入力を拒否したい場合 (たとえば、誰かが 140 文字を超えて入力するのを実際にブロックしたい場合) はFalse
、True
.
ところで、Tk wikiを調べて、 ActiveStateで Tkinter レシピを検索することをお勧めします。誰かがラッパーText
をEntry
持っていて、これらのソリューション (または他のソリューション) を機能させるために必要なすべての余分なものを隠しているので、適切なcount
メソッドを作成するだけでよいのです。スタイルの検証を追加するラッパーさえあるかもしれません。Text
Entry
これを行う方法は他にもいくつかありますが、いずれも欠点があります。
a を追加して、ウィジェットにアタッチされtrace
た へのすべての書き込みをフックします。StringVar
これは、変数への書き込みによって発生します。初めて検証に使用しようとすると、無限再帰ループの問題が発生することを保証します。その後、将来、他のより微妙な問題に遭遇することになります。通常の解決策は、番兵フラグを作成することです。このフラグは、ハンドラーに入るたびにチェックして、再帰的に実行していないことを確認し、再帰イベントをトリガーできる何かを実行しているときに設定します。(edit_modified
上記の例では、フラグを に設定した人を無視することができたので、これは必要ありませんでした。フラグを に設定したFalse
だけFalse
なので、無限再帰の危険はありません。)
<Key>
仮想イベントから新しい文字 (または複数文字の文字列) を取得できます。しかし、その後、あなたはそれで何をしますか?どこに追加されるのか、どの文字が上書きされるのかなどを知る必要があります。シミュレートするすべての作業を行わない場合、Entry
またはさらに悪いことに、Text
自分で編集する場合、これは単にやってlen(entry.get()) + 1
ます。