こんにちは、Rumadra(@rumadra)です。
Tkinterでキーボード入力した内容を表示する方法について調査してみました。
筆者の開発環境はこんな感じです(2020/1/10時点)
Contents
実装方法
以下は簡単に、キー入力された内容を表示するプログラムです。
import tkinter as tk
root = tk.Tk()
root.geometry('300x200')
root.title('サンプルプログラム')
buffer = tk.StringVar() # ①
buffer.set('')
# キーの表示
def print_key(event): # ③
key = event.keysym
buffer.set('入力された値: %s' % key)
# ラベルの設定
tk.Label(root, text='何か入力してください。').pack()
a = tk.Label(root, textvariable=buffer) # ②
a.pack()
a.bind('<Key>', print_key) # ④
a.focus_set() # ⑤
root.mainloop()
実行すると、こんな感じになります。
このように、押されたキーが表示されるようになっています。
実装のポイント
キーボード入力に対応させるためには、次の5つのポイントについて実装する必要があります。
ウィジェット変数を使う
今回はラベルに入力されているキーを表示させました。
buffer = tk.StringVar() # ①
StringVar関数を使うことで入力情報をウィジェットに渡すことができます。
文字列であればStringVar、Int型やDouble型、Boolean型はIntVar、DoubleVar、BooleanVarなどがあります。
詳細はここを確認してください。
buffer.set('入力された値: %s' % key)
ここで入力されたキー情報を格納してます。
ウィジェット変数を紐づける
ウィジェット変数に格納できたら、今度はこれを表示させたいラベルに紐づけます。
a = tk.Label(root, textvariable=buffer) # ②
a.pack()
これだけでOKです。
入力されたキー情報を表示
Tkinterを使ったGUIアプリは、「イベント駆動型プログラム」なので、
何かアクション(イベント)が起こるたびに処理が実行されます。
そのアクションが起きたときの処理を記述したものがこちらになります。
def print_key(event): # ③
key = event.keysym
buffer.set('入力された値: %s' % key)
「keysym」は入力されたキーを識別している番号を表しています。
ラベルにバインドするイベントの種類を指定する
以前この記事でbindの第一引数は空文字として紹介していましたが、どうやらイベントの種別を指定する必要がありました。(bindについて#EVENT TYPESを参照。)
a.bind('<Key>', print_key) # ④
ここで、今回はキーボードの入力をイベントとして受け取りたいので、‘<Key>’ としています。
コメントの方の内容を確認したのち改めて試してみたところ、いつの間にかバインドの種別の指定で怒られるようになってました。
(ちゃんと再現できるように構築環境とかは記録は残しとくべきですね、反省笑🤦♂️)
File "/usr/local/var/pyenv/versions/3.7.4/lib/python3.7/tkinter/__init__.py", line 1206, in _bind
self.tk.call(what + (sequence, cmd))
_tkinter.TclError: no events specified in binding
キー入力を有効にする
最後に、キー入力をラベルに反映させるには、ウィンドウをアクティブにする必要があります。
それを実装するには、おまじないを書いときます。
a.focus_set() # ⑤
ざっとこんな感じでキーボード入力を受け付けられるようになります。
いかがでしょうか。何かありましたら気軽にコメント等ください。
以上、Rumadraでした!
コメント
自分の環境では、
a.bind(“”, print_key)
ではエラーになります。
a.bind(“”, print_key)
なら動作しました。
a.bind(“<Key>”, print_key)
なら動作しました。<>を全角にしないとhtmlでは、タグとみなされて表示が消えるのですね。
あいうえおさん
コメントありがとうございます!
いつの間にか自分の環境でも実行できなくなってました。😅
どうやらイベントの種類を指定しないと判別できないみたいです。
ちなみに、<>が全角でできたということですが、どういう環境か教えていただけませんか?
私の方では全角ではできなかったので…