テキストボックスのフォーカスを切り替え【tkinter】

Python

テキストボックスのフォーカスを切り替え【tkinter】

Python の GUI ライブラリである tkinter では、テキストボックスが入力対象(アクティブになっている)かを『フォーカス』という言葉で表現します。

このフォーカスを自由に切り替える方法を解説します。

本記事は、Python 3.9.7 で動作を確認しています。

focus_set()関数

フォーカスしたいテキストボックスウィジェットの focus_set() メンバ関数を呼び出すだけです。

import tkinter

# ~

entry1 = tkinter.Entry()
entry2 = tkinter.Entry()

# フォーカス変更
entry2.focus_set()

# ~

機能の説明はこれだけで十分!というかたはもうオッケーです。

以降は、実際に動作するソースコードで解説していきます。

基本編

シンプルなEntryウィジェット

テキストボックスを2つ配置したウィンドウ
# ライブラリ取り込み
import tkinter

# トップレベルウィジェット作成
root = tkinter.Tk()
root.geometry("320x240")

# テキストボックスウィジェット作成1
entry1 = tkinter.Entry(root)
entry1.pack()

# テキストボックスウィジェット作成2
entry2 = tkinter.Entry(root)
entry2.pack()

# イベントハンドリング
root.mainloop()

ウィンドウを作成して、テキストボックスを2つ配置するだけのシンプルなプログラムです。

Entry が tkinter のテキストボックスクラスです。

tkinter に見慣れないかたも読みやすくなるよう、最小限のプログラムにしています。コピペで動くようにしてあるので、実際に試してみると良いでしょう。

フォーカスの設定

ひとつ目のテキストボックスがフォーカスされた状態
import tkinter

root = tkinter.Tk()
root.geometry("320x240")

entry1 = tkinter.Entry(root)
entry1.pack()

entry2 = tkinter.Entry(root)
entry2.pack()

# フォーカス設定
entry1.focus_set()

root.mainloop()

Entry ウィジェットの focus_set() を呼び出して、ウィンドウが表示されたときに、ひとつ目のテキストボックスがフォーカスされた状態で起動するようにしています。

任意のテキストボックスが入力できる状態で使い始められるので、これだけでも使い勝手が向上しますよね。

応用編

Enter 入力でフォーカスの切り替え

エンターキーでテキストボックスのフォーカスを切り替え
import tkinter

root = tkinter.Tk()
root.geometry("320x240")

entry1 = tkinter.Entry(root)
entry1.pack()

entry2 = tkinter.Entry(root)
entry2.pack()

# キー入力時のコールバック関数を定義
def on_key1(event):
    entry2.focus_set()

# コールバック関数のバインド
entry1.bind("<Key-Return>", on_key1)

# 以下、entry2用
def on_key2(event):
    entry1.focus_set()

entry2.bind("<Key-Return>", on_key2)

root.mainloop()

今回は、テキストボックスでキーが入力されたタイミングを知る必要があるので、コールバック用の関数を定義して、テキストボックスウィジェットにバインドします。

『<KeyReturn>』は『キーボードエンターキーが押された』という意味で、まさにエンターキーが押されたときに、バインドした関数が呼ばれるようになります。

テキストボックスでエンターキーが押されたときに、それぞれのテキストボックスがフォーカスされるようにしたプログラムです。

上下キー入力でフォーカスの切り替え

上下キーで複数のテキストボックスのフォーカスを切り替え
import tkinter

root = tkinter.Tk()
root.geometry("320x240")

# 作成するウィジェット数
WIDGET_NUM = 10

# ウィジェットをまとめるリスト
widget_list = []

# キー入力コールバック
def on_key(event):
    # キー入力されたウィジェットの要素番号を取得
    idx = widget_list.index(event.widget)
    # 上下キーで要素番号を変動
    if event.keysym == "Up":
        idx -= 1
    elif event.keysym == "Down":
        idx += 1
    # 指定要素へフォーカスを切り替え
    widget_list[idx % len(widget_list)].focus_set()

# ウィジェット作成、バインド、リスト追加
for i in range(WIDGET_NUM):
    entry = tkinter.Entry(root)
    entry.pack()
    entry.bind("<Key>", on_key)
    widget_list.append(entry)

root.mainloop()

上下キーでのフォーカス移動も書いてみました。そういう要望もあるかもしれませんよね。

コールバック関数の引数である event には、キー入力された状況時の様々な情報が格納されています。keysym』プロパティには『どのキー』が押されたかの情報が入っているので、上下キーでそれぞれ条件分岐しています。

また、複数のウィジェットを扱うケースを想定して、リストで管理する方法で実装しました。プログラムは少し難しくなったかもしれませんが、実用力が高めのコードになってきています。

異種ウィジェットでフォーカスの切り替え

テキストボックスやチェックボックスでのフォーカス切り替え
import tkinter

root = tkinter.Tk()
root.geometry("320x240")

# 様々なウィジェットを追加
widget_list = []
widget_list.append(tkinter.Entry(root))
widget_list.append(tkinter.Checkbutton(root, text="chk1"))
widget_list.append(tkinter.Button(root, text="btn1"))
widget_list.append(tkinter.Entry(root))
widget_list.append(tkinter.Checkbutton(root, text="chk2"))
widget_list.append(tkinter.Button(root, text="btn2"))

# キー入力コールバック
def on_key(event):
    idx = widget_list.index(event.widget)
    widget_list[(idx + 1) % len(widget_list)].focus_set()

# ウィジェット配置とキーバインド
for w in widget_list:
    w.pack()
    w.bind("<Key-Return>", on_key)

root.mainloop()

フォーカスの切り替えはテキストボックスに限った機能ではなく、チェックボックスやボタンでもフォーカス切り替えができます。Windows の標準操作である Tab キーで入力したときと同じように振る舞います。

チェックボックスやボタンは Space キーでトリガーが発動するので、フォーカスの切り替えと干渉せずに動作します。

GUI をどう使ってもらいたいか、実装次第で自由にコントロールできますね!

tkinter の技術書籍

残念ながら、tkinter はまともな日本語の書籍がありません。(2021年9月時点)

上記は Python 3.9 に対応した優良書籍(英語)です。

Qiita などで見かける tkinter のプログラムは、正直書き方が古かったり誤用が多い記事ばかりです。まさにその古いプログラムを払拭してくれる書籍になっています。

Python エンジニアなら手元にあってよいでしょう。


今回は、ウィジェットのフォーカス切り替えを重点においた内容にしてみました。

入力項目がアッチやコッチと飛ばされるツールをたまに見かけます。機能が優れていても、使い勝手が悪いツールって敬遠されがちですよね。

開発者なら、誰でも便利と感じてくれる GUI のツールを作りたいはずなので、参考になってくれたら幸いです。

以上、『テキストボックスのフォーカスを切り替え【tkinter】』でした。

Python