Tkinterの使い方:ウィジェット変数について解説【StringVar・BooleanVar・IntVar・DoubleVar】

ウィジェット変数の解説ページのアイキャッチ

このページでは tkinter におけるウィジェット変数(Widget 変数・制御変数)について解説していきたいと思います。

ウィジェット変数(Widget 変数)

まずはウィジェット変数がどのような変数であるかについて解説していきます。

ウィジェット変数は “ウィジェットと連動する変数”

ウィジェット変数は、「ウィジェットと連動する変数」です。別名で「制御変数(Control Variable)」とも呼ばれます。

ウィジェットに “ウィジェット変数” を設定することで、そのウィジェットの表示を動的に変化させたり、そのウィジェットへの入力を動的に取得したりすることができます。つまり、変数とウィジェットが “連動する” ようになります。

例えば、エンリーウィジェットにウィジェット変数を設定しておけば、エントリーへの入力内容が変更された際に、動的にそのウィジェット変数の内容も変更されます。

エントリーとウィジェット変数が連動する様子

また、チェックボタンウィジェットにウィジェット変数を設定しておけば、チェックの有無に応じてウィジェット変数の内容が動的に変更されます。

チェックボタンとウィジェット変数が連動する様子

さらに、ラベルウィジェットにウィジェット変数を設定しておけば、そのウィジェット変数の内容が変更された際に、ラベルの表示内容も動的に変更されます。

ラベルとウィジェット変数が連動する様子

スポンサーリンク

ウィジェット変数と通常の変数との違い

ウィジェット変数と通常の変数との1番の違いは、変数が「ウィジェットと連動する」かどうかです。

ウィジェット変数はウィジェットに設定しておくことでウィジェットと連動してくれますが、通常の変数では連動してくれないので自身で変数やウィジェットの更新をプログラミングする必要があります。

このあたりを踏まえて、通常の変数とウィジェット変数の違いを実際のスクリプトで確認していきたいと思います。

ここでは、「ボタンが押された回数をラベルに表示するアプリ」を作成する例で確認していきたいと思います。

ウィジェット変数を使用せずに通常の変数だけでこれを実現する場合、スクリプトしては例えば下記のようなものになります。

ウィジェット変数を使用しない場合
# -*- coding:utf-8 -*-
import tkinter

# ボタンが押された回数を初期化
count = 0

def updateCount():
	global label
	global count

	# ボタンが押された回数を更新
	count = count + 1

	# ラベルを新しいcountで更新
	label.config(
		text=str(count)
	)

app = tkinter.Tk()

label = tkinter.Label(
	app,
	text=str(count)
)
label.pack()

button = tkinter.Button(
	app,
	text="ボタン",
	command=updateCount
)
button.pack()

app.mainloop()

ポイントは、ボタンが押された時に実行される関数 updateCount です。

この updateCount では、ボタンが押された回数 count を +1 し、さらにそれをラベルウィジェットの text に設定しています。この “ラベルウィジェットへの設定を行わないとラベルが更新されない” ところがポイントです。

通常の変数ではウィジェットと連動しないので、変数の内容に合わせてウィジェットの設定を更新したいような場合は自身でプログラミングしてウィジェットの設定を行う必要があります。

一方で、ウィジェット変数を使用した場合は下記のようなスクリプトとなります。

ウィジェット変数を使用した場合
# -*- coding:utf-8 -*-
import tkinter

def updateCount():
	global label

	# ボタンが押された回数を更新
	new_count = int(count.get()) + 1
	count.set(str(new_count))

app = tkinter.Tk()

count = tkinter.StringVar()
count.set('0')

label = tkinter.Label(
	app,
	textvariable=count
)
label.pack()

button = tkinter.Button(
	app,
	text="ボタン",
	command=updateCount
)
button.pack()

app.mainloop()

count がウィジェット変数になります。

こちらも updateCount 関数でボタンの押された回数を更新していますが、更新先はウィジェット変数 count だけです。

これだけでラベルの表示も自動的に更新されます。

これはウィジェット変数がウィジェットと連動しているからで、ウィジェット変数の内容が更新されれば、そのウィジェット変数を設定しているウィジェットも自動的に更新されます。

こんな感じで、ウィジェットと連動する変数が「ウィジェット変数」になります。

ウィジェット変数の種類

このウィジェット変数には下記の4種類が存在します。

  • StringVar
  • IntVar
  • DoubleVar
  • BooleanVar

これらは全て tkinter に用意されたクラスになります。つまり、ウィジェット変数とはこれらのクラスのインスタンス(オブジェクト)です。このページではこれらのクラスをひっくるめて “ウィジェット変数クラス” と呼ばせていただきます。

これらのクラスの違いは、変数で扱うデータです。各クラスのウィジェット変数が扱うデータは下記のようになります。

  • StringVar:文字列を扱う
  • IntVar:整数を扱う
  • DoubleVar:浮動小数点数を扱う
  • BooleanVar:真偽値(True / False)を扱う

ウィジェット変数の使い方

ウィジェット変数を利用する際に行う基本的な処理は下記の4つになると思います。

  • ウィジェット変数を作成する
  • ウィジェットにウィジェット変数を設定する
  • ウィジェット変数からデータを取得する
  • ウィジェット変数にデータを設定する

スポンサーリンク

ウィジェット変数を作成する

ウィジェット変数は、前述の下記の4種類のクラスのコンストラクタを実行することで作成することができます。

  • StringVar:文字列を扱う
  • IntVar:整数を扱う
  • DoubleVar:浮動小数点数を扱う
  • BooleanVar:真偽値(True / False)を扱う

前述の通り、各クラスで扱うデータが異なるため、ウィジェット変数で扱いたいデータに応じて実行するコンストラクタを選択する必要があります。例えば整数を扱う場合は IntVar() を実行してウィジェット変数を作成します。

下記はこの4種類全てのウィジェット変数を作成するスクリプト例になります。

ウィジェット変数の作成
str_v = tkinter.StringVar()
int_v = tkinter.IntVar()
double_v = tkinter.DoubleVar()
boolean_v = tkinter.BooleanVar()

各コンストラクタの定義は下記のようになっています。

コンストラクタの定義
def __init__(self, master=None, value=None, name=None):

self を除く各引数では、それぞれ下記を指定します。

  • master:親ウィジェット
  • value:初期値
  • name:名前(変数名ではない)

master が省略された場合は自動的にメインウィンドウが親ウィジェットに設定されます。

name が省略された場合は PY_VARxx は整数)が自動的に名前として設定されます。ただおそらくこの名前を利用することはほぼない(print で表示するくらい?)と思いますので設定の必要性は低いです。

ということで設定しておいた方が良いのは value くらいかなぁと思います。ただ、この value を指定しなくても、ウィジェット変数作成後に後述で紹介する set メソッドで設定することも可能です。

value を指定しなかった場合、各ウィジェット変数の初期値は下記のように設定されます。

  • StringVar""
  • IntVar0
  • DoubleVar0.0
  • BooleanVarFalse

ウィジェットを一つも作成していない状態でウィジェット変数クラスのコンストラクタを実行するとエラーが発生するので注意してください。

ウィジェットにウィジェット変数を設定する

続いて、連動させたいウィジェットとウィジェット変数を関連づけるために、ウィジェットに対してウィジェット変数の設定を行います。

ウィジェットにはコンストラクタ実行時や config メソッド実行時に下記のオプションを指定できるものがあります。

  • textvariable
  • variable

textvariable

textvariable は主に “ウィジェットの表示テキストをウィジェット変数と連動させたい場合” に設定します。

下記はラベルウィジェットへの textvariable の設定例になります。

ラベルへのtextvariable設定
# ウィジェット変数を作成
str_v = tkinter.StringVar()

# ラベルウィジェットにウィジェット変数を設定
label = tkinter.Label(
	app, # appはメインウィンドウ
	textvariable=str_v
)
label.pack()

上記のようにラベルウィジェットに textvariable を設定すれば、ウィジェット変数と str_v とラベルウィジェット label が連動するようになります。

より具体的には、str_v が変化した際には label の表示内容がその変化後の str_v に自動的に更新されます。

variable

variable は主に “ウィジェットの設定内容をウィジェット変数と連動させたい場合” に設定します。

例えばチェックボタンウィジェットに variable を設定しておくことで、チェックの有無の切り替えに連動して variable が保持しているデータが変化します。

下記はチェックボタンウィジェットへの variable の設定例になります。

チェックボタンへのvariable設定
# -*- coding:utf-8 -*-
import tkinter

app = tkinter.Tk()

boolean_v = tkinter.BooleanVar()

label = tkinter.Label(
	app,
	textvariable=boolean_v
)
label.pack()

check = tkinter.Checkbutton(
	app,
	variable=boolean_v,
	text="チェックボタン"
)
check.pack()

app.mainloop()

上記のようにチェックボタンウィジェットに variable を設定すれば、ウィジェット変数と boolean_v とチェックボタンウィジェット check が連動するようになります。

より具体的にはチェックボタンウィジェット check へのチェックの有無が変化した際には、boolean_v の値が True or False に自動的に変化します。

この boolean_v が自動的に変化する様子が確認できるようにラベルウィジェット labeltextvariableboolean_v を設定しています。

ラベルウィジェットと boolean_v が連動し、boolean_v が変化するたびに、つまりチェックボタンウィジェットへのチェックの有無が変化するたびに表示内容が変化する様子が確認できると思います。

textvariablevariable の違いはチェックボタンウィジェットが分かりやすいかなぁと思います。

textvariable ではチェックボタンウィジェットの「表示テキスト」がウィジェット変数と連動することになります。

一方で、variable ではチェックボタンの「チェックの有無」がウィジェット変数と連動することになります。

variableとtextvariableの関係

ウィジェット変数からデータを取得する

ウィジェット変数のデータを取得したい場合は、ウィジェット変数クラスに用意された getメソッドを利用します。

get メソッドの定義は下記のようになります。実行すればウィジェット変数が保持しているデータを取得することができます。

get
def get(self):

例えば下記スクリプトでは、ボタンが押された時にチェックボタンのチェックの有無の状態 get で取得し、結果を print で出力する例になります。

getの使用例
# -*- coding:utf-8 -*-
import tkinter

def get_check():
	check = boolean_v.get()

	if check:
		print("チェックされています")
	else:
		print("チェックされていません")

app = tkinter.Tk()

boolean_v = tkinter.BooleanVar()

check = tkinter.Checkbutton(
	app,
	variable=boolean_v,
	text="チェックボタン"
)
check.pack()

button = tkinter.Button(
	app,
	text="ボタン",
	command=get_check
)
button.pack()

app.mainloop()

スポンサーリンク

ウィジェット変数にデータを設定する

ウィジェット変数はウィジェットと連動して自動的にデータが設定されることもありますが、ウィジェット変数にスクリプトからデータを設定することも可能です。

この際にはウィジェット変数クラスに用意された setメソッドを利用します。

set メソッドの定義は下記のようになります。引数 value には各クラスで扱うデータの形式に合わせて指定します。

set
def set(self, value):

set メソッドを実行することで、ウィジェット変数が保持しているデータが変化します。さらに、ウィジェットにウィジェット変数を設定しておけば、ウィジェット変数の変化に連動してウィジェットの表示テキストや設定が変化します。

例えば下記はチェックボタンのチェックの有無を set メソッドで切り替えるスクリプト例になります。もちろん set だけでなくチェックボタンのクリックでチェックを切り替えることも可能です。

setの利用例
# -*- coding:utf-8 -*-
import tkinter

def switch_check():

	check = boolean_v.get()

	if check:
		boolean_v.set(False)
	else:
		boolean_v.set(True)

app = tkinter.Tk()

boolean_v = tkinter.BooleanVar()

check = tkinter.Checkbutton(
	app,
	variable=boolean_v,
	text="チェックボタン"
)
check.pack()

button = tkinter.Button(
	app,
	text="ボタン",
	command=switch_check
)
button.pack()

app.mainloop()

ウィジェット変数の使いどころ

最後にウィジェット変数の使いどころを紹介しておきます。

ウィジェットと変数を連動させたい時

これはここまでの解説でも紹介してきたウィジェット変数の使いどころですね!

特にチェックボタンやラジオボタンなどでは、チェックの有無やラジオボタンのどのボタンが選択されているかに応じて処理を切り替える必要がありますので、コレらの情報を取得するためにウィジェット変数を利用することが多いです。

スポンサーリンク

ウィジェット同士を連動させたい時

また、異なるウィジェットに同じウィジェット変数を設定することで、そのウィジェット同士を連動させるようなことも可能です。

例えば下記では一方のチェックボタンのチェックの有無を切り替えると他方のチェックボタンも連動して切り替わるスクリプト例になります。

ウィジェット同士の連動例1
# -*- coding:utf-8 -*-
import tkinter

app = tkinter.Tk()

boolean_v = tkinter.BooleanVar()

check1 = tkinter.Checkbutton(
	app,
	variable=boolean_v,
	text="チェックボタン1"
)
check1.pack()

check2 = tkinter.Checkbutton(
	app,
	variable=boolean_v,
	text="チェックボタン2"
)
check2.pack()

app.mainloop()

おそらくこの目的でウィジェット変数を利用するケースで一番多いのは下記のような「ラジオボタンウィジェット」同士の連携だと思います。

ウィジェット同士の連動例2
# -*- coding:utf-8 -*-
import tkinter

app = tkinter.Tk()

int_v = tkinter.IntVar()

radio1 = tkinter.Radiobutton(
	app,
	variable=int_v,
	value=1,
	text="ラジオボタン1"
)
radio1.pack()

radio2 = tkinter.Radiobutton(
	app,
	variable=int_v,
	value=2,
	text="ラジオボタン2"
)
radio2.pack()

label = tkinter.Label(
	app,
	textvariable=int_v,
)
label.pack()

app.mainloop()

ラジオボタンの特徴は「グループ内のボタンが1つのみ選択できるボタン」である点です。そして、tkinter でこれを実現するのがウィジェット変数です。

ラジオボタンでは、ボタンが選択されると variable が各ボタンに設定されている value のデータに自動的に変化します。

さらに各ボタンは、valuevariable のデータが一致しているもののみが “選択中の見た目” に自動的に変化します。つまりそれぞれのラジオボタンに異なる value を設定しておけば、違うボタンが選択されると value != variable となり自動的に選択が外れます。

なので、複数のラジオボタンそれぞれに異なる value を設定し、さらに variable に同じウィジェット変数を設定しておけば、あとはラジオボタンとウィジェット変数が連動し、それらのボタンの1つのみが選択可能なラジオボタンとして機能するようになります。

ラジオボタンとウィジェット変数の連動

ウィジェット変更時に処理を実行したい時

また、ウィジェット変数を用いてウィジェットに対して操作が行われたときに特定の関数やメソッドを実行させるようなことも可能です。

例えばチェックボタンのチェックの有無が切り替えられた時や、エントリーの入力文字列が変更された際に、自動的に特定の処理を実行させるようなことができます。

trace_add

このようにウィジェットに対する操作に対して自動的に特定の処理を実行させたい場合には、あらかじめ下記の trace_add を実行しておく必要があります。

trace_add
def trace_add(self, mode, callback):

trace_add は実行したウィジェット変数に対する mode で指定した動作が行われたときに callback で指定した関数もしくはメソッドが自動的に実行されるように設定を行うメソッドになります。

trace_addmode

mode で指定可能な動作は下記の3つになります。

  • 'write':ウィジェット変数のデータが変更された
  • 'read':ウィジェット変数のデータが取得された
  • 'unset':ウィジェット変数が破棄された

mode'write' を設定しておけば、ウィジェットに対して操作が行われた際に、そのウィジェットと連動するウィジェット変数のデータが変更され、自動的に callback で指定した関数やメソッドが実行されるようになります。

他にも 'read' を設定しておくことでウィジェット変数のデータが取得された際に自動的に特定の処理を実行させるようなことも可能です。

mode には複数を同時に指定することも可能で、この場合は下記のようにタプル形式で指定します。

modeの複数
# vはウィジェット変数クラスのインスタンス
v.trace_add(('write', 'read', 'unset'), callback)

trace_addcallback

callback には前述の通り自動的に実行されるようにしたい関数やメソッドを指定します。これらの関数やメソッドでは、下記のように引数を取る必要があります。

callbackに指定する関数
def callback(arg1, arg2, arg3):
callbackに指定するメソッド
def callback(self, arg1, arg2, arg3):

各引数の意味は下記のようになります。ポイントは self 引数を3つ分受け取る必要があるところです。

  • arg1mode で指定した動作が発生したウィジェット変数の名前
  • arg2:すみません、この引数の意味がわかりませんでした…
  • arg3:発生した動作('write', 'read' or 'unset'

trace_add の利用例

下記が trace_add の利用例になります。

trace_addの利用例
# -*- coding:utf-8 -*-
import tkinter

def callback(arg1, arg2, arg3):
	print(arg1 + 'に' + arg3 + 'が発生しました')

def read_func():

	# 'read'を発生させる
	print(str_v.get())

def unset_func():
	global str_v

	# 'unset'を発生させる
	str_v = None

app = tkinter.Tk()

str_v = tkinter.StringVar()

entry = tkinter.Entry(
	app,
	textvariable=str_v,
	width=10
)
entry.pack()

button = tkinter.Button(
	app,
	text="取得",
	command=read_func
)
button.pack()

button = tkinter.Button(
	app,
	text="破棄",
	command=unset_func
)
button.pack()

# str_vに動作が発生したときにcallbackを実行させるように設定
str_v.trace_add(('write', 'read', 'unset'), callback)

app.mainloop()

下記が行われると関数 callback が実行されるようになっています。

  • エントリーウィジェットの文字列が変更された時('write' が発生)
  • 「取得」ボタンが押された時(read_func の中で get メソッドが実行され、この時に 'read' が発生)
  • 「破棄」ボタンが押された時(unset_func の中で str_v = None が実行され、GC が動作して  'unset' が発生)

まとめ

このページでは tkinter における「ウィジェット変数」について解説しました!

ウィジェット変数は「ウィジェットと連動する変数」です。ウィジェットと連動するというところが通常の変数と異なります。

ウィジェット変数を用いることで下記のようなことを簡単に実現することができます。

  • ウィジェットと変数を連動させる
  • ウィジェット同士を連動させる
  • ウィジェット変更時に処理を実行する

特にチェックボタンやラジオボタン等を利用する時にはこのウィジェット変数の利用が必須になります!是非これらのウィジェットを利用しながらウィジェット変数への理解を深めてみてください!

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です