LoginSignup
5
3

More than 3 years have passed since last update.

TkinterでCheckbuttonにチェックを付けると、Entryが編集できるようにする

Last updated at Posted at 2020-08-09

環境:
Ubuntu 18.04.5 LTS (Windows Subsystem for Linux)
Python 3.8.0
VcXsrv 1.20.5.1

目標

PythonのTkinterでチェックボックス(Checkbutton)にチェックをつけると、入力欄(Entry)が有効になり入力できるようにする。
チェックを外すと、編集できなくする。
check.png
checkme.png

方法

import tkinter as tk

def change_state():
    if bool_check.get():
        # チェックをつけたとき
        entry.config(state='normal')
    else:
        # チェックをはずしたとき
        entry.config(state='disabled')

root = tk.Tk()

entry = tk.Entry()
entry.config(state='disabled')  # 最初は無効

bool_check = tk.BooleanVar()
bool_check.set(False)  # 最初はチェックなし
check = tk.Checkbutton(variable=bool_check, command=change_state)

check.pack()
entry.pack()

root.mainloop()

change_state関数を定義します。

変数名は何でもいいですが、例えばbool_check変数にtk.BooleanVar()を代入します。
tk.Checkbutton()の引数variableにbool_check変数を、引数commandにchange_state関数を渡してチェックボックスを作成します。

チェックの有無はbool_check.get()でブール値で返されます。
チェックをつけはずしするとchange_state()が呼ばれます。

change_state()では作製したentryのstateをチェックの有無に応じて変更します。

2つ以上作りたいとき

change_state()にbool_checkやentryを引数として渡せられれば、2つ以上の入力欄で同様のことができそうです。
likethis.png
しかしながら例えば、

def change_state(bool_check, entry):
    if bool_check.get():
        entry.config(state='normal')
    else:
        entry.config(state='disabled')

のようにchange_state関数を引数付きで定義して、

tk.Checkbutton(command=change_state(bool_check, entry))

のようにtk.Checkbutton()のcommand引数に、引数付きの関数を渡しても正しく動作しません。
正しく動作するには、commandにlambda式を渡します。すなわち、

import tkinter as tk

def change_state(bool_check, entry):
    if bool_check.get():
        entry.config(state='normal')
    else:
        entry.config(state='disabled')

root = tk.Tk()

# 1つ目
entry1 = tk.Entry()
entry1.config(state='disabled')
bool_check1 = tk.BooleanVar()
bool_check1.set(False)
check1 = tk.Checkbutton(text='1', variable=bool_check1,
                        command=lambda: change_state(bool_check1, entry1))
check1.pack()
entry1.pack()

# 2つ目
entry2 = tk.Entry()
entry2.config(state='disabled')
bool_check2 = tk.BooleanVar()
bool_check2.set(False)
check2 = tk.Checkbutton(text='2', variable=bool_check2,
                        command=lambda: change_state(bool_check2, entry2))
check2.pack()
entry2.pack()

root.mainloop()

こちらの書き方の方が、change_state関数がグローバル変数に依存せず良いような気がします。

簡単な応用

チェックをはずすと、入力されていた文字列を削除して"無効"を表示してみる。

aaa.png
mukou.png

import tkinter as tk

def change_state():
    if bool_check.get():
        # チェックをつけたとき
        entry.config(state='normal')
        entry.delete(0, tk.END)  # normalにしてから"無効"をdeleteする
    else:
        # チェックをはずしたとき
        entry.delete(0, tk.END)  # 0文字目から終わりまで文字列を削除する
        entry.insert(0, "無効")  # Entryの0文字目に"無効"をinsert
        entry.config(state='disabled')  # insertしてからdisableにする

root = tk.Tk()

entry = tk.Entry()
entry.insert(0, "無効")  # Entryの0文字目に"無効"をinsert
entry.config(state='disabled')  # insertしてからdisableにする

bool_check = tk.BooleanVar()
bool_check.set(False)
check = tk.Checkbutton(variable=bool_check, command=change_state)

check.pack()
entry.pack()

root.mainloop()

初期値を与えるなど、応用ができそうです。

5
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
3