【Python】画面にキーボード入力を認識させてみた【Tkinter】

Python

こんにちは、Rumadra(@rumadra)です。

 

Tkinterでキーボード入力した内容を表示する方法について調査してみました。

 

筆者の開発環境はこんな感じです(2020/1/10時点)

macOS Catalina バージョン10.15.2
Python 3.7.4

 

実装方法

以下は簡単に、キー入力された内容を表示するプログラムです。

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型はIntVarDoubleVarBooleanVarなどがあります。

詳細はここを確認してください。

 

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>’ としています。

 

余談ですが、当時はなぜか空文字でもできてました。(Pythonのバージョンは変えていないはず…??)
コメントの方の内容を確認したのち改めて
試してみたところ、いつの間にかバインドの種別の指定で怒られるようになってました。
(ちゃんと再現できるように構築環境とかは記録は残しとくべきですね、反省笑🤦‍♂️)
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() # ⑤

 

 

ざっとこんな感じでキーボード入力を受け付けられるようになります。

いかがでしょうか。何かありましたら気軽にコメント等ください。

 

コメント指摘ありがとうございます!!修正しました。(2020/1/10)

 

以上、Rumadraでした!

 

コメント

  1. あいうえお より:

    自分の環境では、

    a.bind(“”, print_key)
    ではエラーになります。

    a.bind(“”, print_key)
    なら動作しました。

  2. あいうえお より:

    a.bind(“<Key>”, print_key)
    なら動作しました。<>を全角にしないとhtmlでは、タグとみなされて表示が消えるのですね。

    • rumadra より:

      あいうえおさん
      コメントありがとうございます!
      いつの間にか自分の環境でも実行できなくなってました。😅

      どうやらイベントの種類を指定しないと判別できないみたいです。

      ちなみに、<>が全角でできたということですが、どういう環境か教えていただけませんか?
      私の方では全角ではできなかったので…

タイトルとURLをコピーしました