Tkinterの使い方:スピンボックス(Spinbox)の使い方

スピンボックウィジェットの使い方の解説ページアイキャッチ

このページでは tkinter のウィジェットの1つである「スピンボックス( Spinbox クラス)」の使い方について解説していきます。

MEMO

私の下記環境での実行結果をもとに説明していますが、環境によっては動きが異なるかもしれません

実際にご自身の環境で実行結果を確認していただくと、より確実に設定の効果を理解することができると思います

  • OS:macOS Big Sur
  • Python:3.9.4
  • Tkinter:8.6

スピンボックスウィジェット

まずは、スピンボックスウィジェットがどのようなウィジェットであるのかについて解説していきます。

スピンボックスウィジェットとは

スピンボックスは下の図のようなウィジェットになります(OS 等の環境によっては見た目が異なる可能性があります)。

スピンボックスウィジェットを示す図

このページでは、このスピンボックスウィジェットの各部品を、大きく分けて下図のように「エントリー部」「上下ボタン」と呼ばせていただきます。また、上下ボタンそれぞれのボタンを区別して呼ぶ場合は「上ボタン」「下ボタン」と呼ばせていただきます。さらに、エントリー部に表示される値を「スピンボックスの値」と呼ばせていただきます。

スピンボックスの各部品の名称の説明図

スピンボックスでは、上下ボタンをクリックすることでスピンボックスの値を増減させることができます。

スピンボックスの上下ボタンで値を変化させる様子

さらには、エントリー部からスピンボックスの値を直接編集することで値を変更することも可能です。

スピンボックスは、上記のような操作によってアプリの設定の変更をユーザーから受け付けることを目的とするウィジェットになります。

もちろん、ユーザーにただ値を変更してもらうだけでは意味がないので、アプリとしてはユーザーが設定した値に応じて、処理を切り替えるような動作を実現する必要があります。

スピンボックスの値に応じてアプリの動作を切り替える例を示す図

ユーザーからの値の変更を受け付けるという意味では、下記ページで紹介しているスケールウィジェットに似ていると思います。

スケールウィジェットの使い方の解説ページアイキャッチTkinterの使い方:スケール(Scale)の使い方

スケールウィジェットではスライダーの移動によりユーザーから値の変更を受け付けますが、このページで紹介するスピンボックスでは、上下ボタンや値の直接編集によって値の変更を受け付けることになります。

また、スピンボックスの左側のエントリー部は、その名の通り、下記ページで紹介しているエントリーウィジェットと同様の部品になります。ですので、スピンボックスウィジェットは「エントリーウィジェット+上下ボタン」と考えても良いと思います。

エントリーウィジェットの説明ページアイキャッチTkinterの使い方:エントリー(Entry)の使い方

実際、後述の スピンボックスのオプション で紹介するスピンボックスの動作や見た目の詳細を設定するオプションや、スピンボックスのメソッド で紹介するメソッドに関してはエントリーウィジェットと同様のものが多いです。

スポンサーリンク

スピンボックスの使い方

では、このスピンボックスの使い方について解説していきたいと思います。

まずは、このスピンボックスを利用した簡単なアプリのスクリプト例を示したいと思います。

スピンボックスの利用例
# -*- coding:utf-8 -*-
import tkinter

def change_fill():
	# スピンボックスの値を整数に変換
	value = int(spinbox.get() )

	# 整数を2桁の16進数表記の文字列に変換
	r = format(value, '02x')
	g = format(value, '02x')
	b = format(value, '02x')

	# 文字列を結合してカラーコードを作成
	color = "#" + r + g + b

	# そのカラーコードを長方形の塗りつぶし色に反映
	canvas.itemconfig(rect, fill=color)

app = tkinter.Tk()

canvas = tkinter.Canvas(
	app,
	width=300,
	height=200,
	bg="#FFFFFF",
	highlightthickness=0
)
canvas.pack()

rect = canvas.create_rectangle(
	10, 10, 289, 189,
	fill="#000000"
)

# スピンボックスウィジェットの作成と配置
spinbox = tkinter.Spinbox(
	app,
	from_=0,
	to=255,
	increment=10,
	command=change_fill
)
spinbox.pack(padx=10, pady=10)

app.mainloop()

上記スクリプトで使用している各メソッドについては、それぞれ下記のページで解説していますので、詳しく知りたい方はこれらのページをご参照していただければと思います

上記スクリプトを実行すれば、次の図のようなアプリが起動します。

サンプルスクリプトを実行すると起動するアプリ

上側に表示されているのがキャンバスウィジェットで、下側に表示されているのが、このページで解説を行うスピンボックウィジェットになります。

このスピンボックスウィジェットの上下ボタンをマウスでクリックすればスピンボックスの値が変化し、それに応じてキャンバスに描画された長方形の色が変化します。

サンプルスクリプトで起動するアプリの動作を示すアニメ

要は、スピンボックの値を取得し、長方形の色をその値に応じて設定することで、上のアニメのような動作を実現しています。

こんな感じでスピンボックスを使用する際には、単にスピンボックスを作成するだけでなく、スピンボックスの値を取得し、その値に応じて動作を切り替えるような処理を記述する必要があります。

ですので、スピンボックスウィジェットを使用する際には、スピンボックスウィジェット関連では下記の2つの処理が最低限必要になります。

  • スピンボックスウィジェットの作成
  • スピンボックスの値の取得

ここからは、上記2つの処理の実現方法について解説していきたいと思います。

スピンボックスの作成

リストボックスウィジェットは、tkinter の Spinbox クラスのコンストラクタを実行することで作成することができます。

スピンボックスの作成
# app はメインウィンドウ等の親ウィジェット
spinbox = tkinter.Spinbox(
	app
)

上記の Spinbox クラスのコンストラクタで作成したスピンボックスウィジェットを spinbox.pack() 等で配置すると、下の図のようなウィジェットがアプリ上に表示されるようになります。

オプションなしで作成したスピンボックス

スピンボックス自体は作成できてはいるのですが、肝心のスピンボックスの値が表示されていないですね…。実際に上記で作成したスピンボックスの上下ボタンをクリックしてみると、値も変化しないことも確認できると思います(そもそも値が表示されていないので当然ですが…)。

この値を表示したり、上下ボタンをクリックして値を変化させるためには、tkinter.Spinbox() 実行時にオプションを指定する必要があります。

例えば数値を表示する場合、 from_ オプションと to オプションを指定すれば、スピンボックスに値を表示し、上下ボタンでその数値を変化させることができるようになります。

より具体的には、下記のように tkinter.Spinbox() を実行した後に spinbox.pack() 等でスピンボックウィジェットをアプリに配置するようにすれば、スピンボックスウィジェットに 0 が表示されるようになるはずです。

値を表示するためのオプション指定
# app はメインウィンドウ等の親ウィジェット
spinbox = tkinter.Spinbox(
	app,
	from_=0,
	to=255,
)

上下ボタンをクリックすれば、数値が変化することも確認できると思います。この数値は 0255 の間で変化させることが可能です。

こんな感じで、スピンボックスで値を表示したり上下ボタンで値を変化させられるようにしたりするためには、tkinter.Spinbox() 実行時にオプションを指定する必要があるので注意してください。

今回は from_to のオプションを指定しましたが、他のオプションにより数値でなく文字列をスピンボックスの値として扱うこともできるようになります。

また、スピンボックスの値に関するオプションだけでなく、スピンボックスの見た目や動作などを細かく設定するためのオプションがスピンボックスウィジェットには用意されています。

これらのオプションにつきましては、後述の スピンボックスのオプション で解説していきたいと思います。

さて、先程作成したスピンボックスでは、from_ オプションと to オプションの指定することで上下ボタンのクリックにより数値を変化させることができるようになりました。

ですが、現状だとその数値を変更したところで、アプリの動作としては全く変わりません。これは、スピンボックスの値に応じてアプリの処理を切り替えるような処理が行われていないからです。

そして、スピンボックスの値に応じてアプリの処理を切り替えるような処理を実現するためには、まずはスピンボックスの値の取得を行う必要があります。

次は、このスピンボックスの値の取得を行う方法について解説していきます。

スピンボックスの値の取得

スピンボックスの値を取得する方法としては大きく分けて下記の2つが存在します。

  • スピンボックスウィジェットの get メソッドで取得する
  • ウィジェット変数の get メソッドで取得する

スピンボックスウィジェットの get メソッドで取得する

スピンボックスウィジェットのクラスである Spinbox には get メソッドが用意されており、この get メソッドによりスピンボックスの値を取得することが可能です。

下記は、ボタンクリック時にスピンボックスウィジェットの get メソッドを実行してスピンボックスの値を取得し、その値をラベルウィジェットの表示文字列に反映するスクリプトの例になります。

スピンボックスウィジェットのgetでの取得
# -*- coding:utf-8 -*-
import tkinter

def change_label():
	# スピンボックス値をgetメソッドで取得
	value = spinbox.get()

	# 取得した値をラベルの表示文字列に反映
	label.config(text=str(value))

app = tkinter.Tk()

label = tkinter.Label(
	app,
	text="0",
	font=("", 80),
	width=10
)
label.pack(padx=10, pady=10)

# スピンボックスウィジェットの作成と配置
spinbox = tkinter.Spinbox(
	app,
	from_=0,
	to=255
)
spinbox.pack(padx=10, pady=10)

button = tkinter.Button(
	app,
	command=change_label,
	text="変更"
)
button.pack(padx=10, pady=10)

app.mainloop()

change_label 関数の下記部分が、スピンボックスウィジェット spinbox の値を get メソッドにより取得している部分になります。

ウィジェットのgetメソッドによる値の取得
value = spinbox.get()

このスクリプトを実行すると下の図のようなアプリが表示されます。

スピンボックスウィジェットに用意されたgetメソッドにより値を取得するアプリのサンプル

スピンボックスの上下ボタンをクリックしてスピンボックスの値を変更後に “反映ボタン” をクリックすれば、スピンボックスの値をラベルウィジェットに表示することができます(スピンボックスの値を直接編集しても良いです)。

スピンボックスウィジェットに用意されたgetメソッドにより値を取得し、その値をラベルウィジェットに反映する様子

上記スクリプトにおいては、ボタンウィジェットがクリックされたことを契機にスピンボックスの値を取得し、その値をラベルウィジェットに反映するようにしていますが、スピンボックスの command オプションを利用することで、上下ボタンをクリックされたことを契機にスピンボックスの値を取得し、その値を他のウィジェットに反映するようなことも可能です。

この command オプションについては、後述の スピンボックスのオプションcommand で紹介していきたいと思います。

また、command オプションを指定しなくても、次のウィジェット変数を利用する方法であれば、スピンボックスの値が変化したことを契機に変化後の値を他のウィジェットに反映することも可能になります。

ウィジェット変数の get メソッドで取得する

次は、スピンボックスの値を取得するための方法として、ウィジェット変数を利用する方法を説明します。

まだウィジェット変数についてご存知ない方は、下記のページで詳しく解説していますので宜しければこちらをご覧いただければと思います。

ウィジェット変数の解説ページのアイキャッチTkinterの使い方:ウィジェット変数について解説【StringVar・BooleanVar・IntVar・DoubleVar】

ウィジェット変数をスピンボックスと連動させておくことで、スピンボックスの値をウィジェット変数の get メソッドにより取得することが可能になります。

ウィジェット変数には IntVarDoubleVarBooleanVarStringVar が存在しますが、取得したスピンボックスの値をどういう型で扱いたいのかに合わせて利用するウィジェットを選択すれば良いです。

例えばスピンボックスの値が整数なのであれば、基本的には IntVar を利用するので良いのですが、もし値を取得したときに浮動小数点数として扱いたいのであれば DoubleVar の方が適していると思います。

下記は、ボタンクリック時にウィジェット変数の get メソッドを実行してスピンボックスの値を取得し、その値をラベルウィジェットの表示文字列に反映するスクリプトの例になります。

ウィジェット変数のgetでの取得
# -*- coding:utf-8 -*-
import tkinter

def change_label():
	# スピンボックス値をウィジェット変数のgetメソッドで取得
	value = var.get()

	# 取得した値をラベルの表示文字列に反映
	label.config(text=str(value))

app = tkinter.Tk()

# ウィジェット変数の作成
var = tkinter.IntVar(app, value=0)

label = tkinter.Label(
	app,
	text="0",
	font=("", 80),
	width=10
)
label.pack(padx=10, pady=10)

# スピンボックスウィジェットの作成と配置
spinbox = tkinter.Spinbox(
	app,
	from_=0,
	to=255,
	textvariable=var # ウィジェット変数を設定
)
spinbox.pack(padx=10, pady=10)

button = tkinter.Button(
	app,
	command=change_label,
	text="ボタン"
)
button.pack(padx=10, pady=10)

app.mainloop()

change_label 関数の下記部分が、ウィジェット変数 var から get メソッドによりスピンボックスの値を取得している部分になります。

ウィジェット変数のgetメソッドによる値の取得
value = var.get()

アプリの動作は スピンボックスウィジェットの get メソッドで取得する で紹介した例と全く同じなので説明は省略します。

上記の例の場合は、単にスピンボックスウィジェットとウィジェット変数を連動させているだけですが、ウィジェット変数を利用してスピンボックスウィジェットと他のウィジェットを連動させるようなことも可能です。

下記がスピンボックスウィジェットとラベルウィジェットを連動させる例になります。

スピンボックスとラベルの連動
# -*- coding:utf-8 -*-
import tkinter

app = tkinter.Tk()

# ウィジェット変数の作成
var = tkinter.IntVar(app, value=0)

label = tkinter.Label(
	app,
	font=("", 80),
	width=10,
	textvariable=var # ウィジェット変数を設定
)
label.pack(padx=10, pady=10)

# スピンボックスウィジェットの作成と配置
spinbox = tkinter.Spinbox(
	app,
	from_=0,
	to=255,
	textvariable=var # ウィジェット変数を設定
)
spinbox.pack(padx=10, pady=10)

app.mainloop()

下記のように、スピンボックス作成時(tkinter.Spinbox() 実行時)とラベル作成時(tkinter.Label 実行時)に textvariable オプションに同じウィジェット変数 var を指定しているところがポイントです。

スピンボックスのウィジェット変数の設定
# スピンボックスウィジェットの作成と配置
spinbox = tkinter.Spinbox(
	# 略
	textvariable=var # ウィジェット変数を設定
)
ラベルのウィジェット変数の設定
label = tkinter.Label(
	# 略
	textvariable=var # ウィジェット変数を設定
)

これにより、スピンボックスの値が変化するとウィジェット変数の値も変化し、その変化に連動してラベルウィジェットの値も変化するようになります。

スクリプトを実行してアプリのスピンボックスの値を変更すれば、自動的にラベルの表示文字列が変化することが確認できると思います。

スピンボックスの値の変更に連動してラベルウィジェットの表示が自動的に変化する様子

ポイントは、先程紹介したスクリプトと違い、わざわざボタンをクリックしなくてもスピンボックスの値がラベルウィジェットに反映されるところですね!

同じウィジェット変数 var をスピンボックスとラベルに設定していますので、var が変更されると自動的にこれらのウィジェットに反映されるようになります。

より具体的には、スピンボックスの値が変化した際にはウィジェット変数 var に自動的にスピンボックスの値が設定され、このウィジェット変数 var の変化に伴いその値がラベルに自動的に反映されるようになっています。

ウィジェット変数を介してスピンボックスとラベルが連動する様子を示した図

自動的に反映されるので便利ですが、ウィジェット変数を設定できないウィジェットなどもあるので注意してください。

例えば前述で紹介したキャンバスに描画済みの図形の色を変更するような場合、図形にはウィジェット変数を設定できないため、この方法でスピンボックスの値を自動的に図形の色に反映することはできません。

スポンサーリンク

スピンボックスのオプション

基本的なスピンボックスウィジェットの使い方は前述の通りになります。

ここからは、より詳細なスピンボックウィジェットの解説を行なっていきます。

まずはスピンボックスのオプションについて解説していきたいと思います。

他のウィジェット同様、スピンボックスもウィジェット作成時(tkinter.Spinbox 実行時)にオプションを指定することで、スピンボックスウィジェットの詳細(見た目など)を設定することが可能です(作成時だけでなく、後から config メソッドで変更することも可能)。

スピンボックスウィジェットに指定可能なオプションの一覧は、下記により表示することが可能です。

指定可能なオプションの一覧
# spinboxはSpinboxのインスタンス
print(spinbox.keys())

スピンボックスウィジェットとは でも解説したように、スピンボックスは言ってしまえばエントリーウィジェットに上下ボタンが付加されたものです。

そのため、スピンボックスウィジェットに指定可能なオプションは、下記ページで解説しているエントリーウィジェットのオプション同様のものが多いです。

エントリーウィジェットの説明ページアイキャッチTkinterの使い方:エントリー(Entry)の使い方

特に下記に関しては意味合いがほぼ同じですので、これらのオプションの解説については、すみませんがエントリーウィジェットの方のオプションの解説を参照していただければと思います(オプション名にリンクを貼っていますので、クリックすればエントリーウィジェットに対する解説が表示されるようになっています)。

また、下記のオプションについてはスピンボックスにスクロールバーを付けるためのものになります。

  • xscrollcommand

このオプションを利用したスクロールバー付きのスピンボックスの作り方については下記ページの スクロールバー付きのスピンボックス で紹介していますので、これらのオプションについて詳しく知りたい方は下記のページを参照していただければと思います。

スクロールバーの作成方法解説ページアイキャッチTkinterの使い方:スクロールバー(Scrollbar)の使い方

さらに、下記の5つのオプションは、スピンボックスの値に対する validation 機能(スピンボックの値の妥当性の確認機能)に関するオプションになります。

  • validate
  • validatecommand
  • vcmd
  • invalidcommand
  • invcmd

これらに関しては下記ページで解説していますので、特に validation 機能について知りたい、validation 機能を使いたい方は下記ページを読んでみていただければと思います。

validationの解説ページアイキャッチTkinterの使い方:validation機能の使い方(エントリーウィジェットの拡張)

ただ、私の環境では上記のオプションを指定することはできるものの、validation 機能がうまく動作してくれませんでした(後述の from_to オプションや values オプションを指定すると正常に動作しなくなる)。

同じく validation 機能が動作しない環境の人もおられると思いますので、この点はご注意ください。

このページでは、上記で挙げたオプションを除いた下記のオプションについて解説していきます。

MEMO

下記の2つのオプションについては、私の環境ではうまく動作させられなかったので解説は省略させていただいています

  • activebackground
  • exportselection

おそらくですが、前者はマウスカーソルがスピンボックスウィジェット上に移動した時の背景色を指定するオプションで、後者はスピンボックスウィジェットの値のコピペを許可する or 許可しないを切り替えるためのオプションになると思います

from_to

from_ はスピンボックスで設定できる値の最小値を、 to はスピンボックスで設定できる値の最大値を指定するオプションになります。from ではなく from_ である点に注意してください(アンダーバーが必要)。

from_・toオプションの説明図

また、to に指定する値は from_ よりも大きな値である必要があります。

例えば、from_=x かつ to=y とオプション指定した場合、スピンボックスの値の取りうる範囲は xy のみとなります(スピンボックスの値を直接変数して xy 以外に設定した場合、次に上下ボタンを押されたときに自動的に xy の値に設定されます)。

from_ および to のデフォルト値は 0 になります。このデフォルト値では from_ < to の関係が満たされないため、おそらくスピンボックスは正常に動作しないと思います(私の環境では何も値が表示されない)。

ですので、スピンボックスウィジェット使用する際には、必ず from_ < to の関係を満たすように from_ と to のどちらか一方、もしくは両方のオプション指定を行う必要があります。 

下記はスピンボックスウィジェットの最小値を-50 に、最大値を 250 にそれぞれ指定する例になります。

from_とtoの指定例
spinbox = tkinter.Spinbox(
	app, # 親ウィジェット
	from_=-50,
	to=250
)

increment

increment はスピンボックスの上下ボタンのクリック時に値が増減する量を指定するオプションになります。

incrementオプションの説明図

increment のデフォルト値は 1 になります。

increment0.1 などの 1 よりも小さい正の値を指定することで、スピンボックスで小数点以下の値も扱うことも可能です(小数点以下の値も扱いたい場合は、後述で紹介する format オプションも合わせて使用した方が無難だと思います)。

下記は、上下ボタンのクリック時の増減量を20 に指定する例になります。

incrementの指定例
spinbox = tkinter.Spinbox(
	app, # 親ウィジェット
	from_=-50,
	to=250,
	increment=20
)

スポンサーリンク

values

values はスピンボックスに設定可能な値を直接タプル形式で指定するオプションになります。

valuesオプションの説明図

例えば下記のように values オプションを指定した場合、上下ボタンの上ボタンをクリックすれば、スピンボックスの値が 2357111317 と変化していくことになります。

valuesの指定例1
spinbox = tkinter.Spinbox(
	app, # 親ウィジェット
	values=(2, 3, 5, 7, 11, 13, 17)
)

また、values に指定するタプルの各要素を文字列にしてしまえば、上下ボタンクリック時に設定されるスピンボックスの値を文字列にすることも可能です。

valuesの指定例2
spinbox = tkinter.Spinbox(
	app, # 親ウィジェット
	values=("red", "green", "blue")
)

values が指定されている場合、下記のオプションは無視されることになります。

  • from_
  • to
  • increment

wrap

wrap はスピンボックスの値が最大値である場合に上ボタンがクリックされた時の動作、および、スピンボックスの値が最小値である場合に下ボタンがクリックされた時の動作を指定するオプションになります。

wrap のデフォルト値は False0)であり、この場合、スピンボックスの値が最大値である状態で上ボタンがクリックされても値は変化しません。同様に、スピンボックスの値が最小値である状態で下ボタンがクリックされても値は変化しません。

wrapオプションの説明図1

wrapTrue1)を指定した場合、スピンボックスの値が最大値である状態で上ボタンがクリックされると、値が最小値に変化するようになります。同様に、スピンボックスの値が最小値である状態で下ボタンがクリックされると、値が最大値に変化するようになります。

wrapオプションの説明図2

例えば下記のようにスピンボックスを作成した場合、255 が表示されている状態で上ボタンをクリックすれば値が 0 に変化します。同様に 0 が表示されているボタンで下ボタンをクリックすれば値が 255 に変化します。

wrapの指定例1
spinbox = tkinter.Spinbox(
	app, # 親ウィジェット
	from_=0,
	to=255,
	wrap=True
)

前述の通り、スピンボックスの値として取りうる値を values により指定することができ、この場合でも wrap オプションは指定可能です。

例えば下記のようにスピンボックスを作成すれば、スピンボックスの値が "blue" の時に上ボタンをクリックすればスピンボックスの値が "red" に変化し、スピンボックスの値が "red" の時に下ボタンをクリックすればスピンボックスの値が "blue" に変化するようになります。

wrapの指定例2
spinbox = tkinter.Spinbox(
	app, # 親ウィジェット
	values=("red", "green", "blue"),
	wrap=True
)

command

command はスピンボックスの上下ボタンがクリックされたときに実行する関数(メソッド)を指定するオプションになります。

commandオプションの説明図

スピンボックスの上下ボタンがユーザーによってクリックされた際に何らかの処理を行いたい場合は、この command オプションが便利だと思います。

例えば スピンボックスの使い方 の最初に紹介しているスクリプトでは、スピンボックスの command オプションに change_fill 関数を指定しており、ユーザーが上下ボタンをクリックした際には、この change_fill 関数の中からキャンバスに描画されている長方形の色をスピンボックスの値に応じた色に変化させるようにしています。

command オプションで指定した関数が実行される際には、”引数なし” として関数が実行されます。引数でスピンボックスの値が渡されてくるようなことはありませんので、必要に応じてスピンボックスの値を取得するような処理を関数内に記述してやる必要があります(取得の仕方については スピンボックスの値の取得 で解説しています)。

スポンサーリンク

state

state はスピンボックスの状態を指定するオプションになります。

stateオプションの説明図

スピンボックスウィジェットの state に指定可能なパラメータは下記の3つになります。

  • tkinter.NORMAL:通常状態(デフォルト)
  • tkinter.DISABLED:無効状態
  • "readonly":読み取り専用状態
    • (もしかしたら上記のように定義名があるかも)

tkinter.NORMAL を指定した場合、ユーザーはスピンボックスの値を上下ボタンで変更することもできますし、直接編集する事も可能です。

"readonly" を指定した場合、ユーザーはスピンボックスの値を上下ボタンでのみ変更可能になります。直編集することはできません。

tkinter.DISABLED を指定した場合は、ユーザーはスピンボックスの値を変更することはできなくなります(上下ボタンも効かない)。

結構使えると思うのが "readonly" 指定です。

スピンボックスの値を直接編集できてしまうと、ユーザーに思わぬ値に設定されてしまう可能性があります。例えば整数のみをスピンボックスの値として扱いたいのに、文字列などを設定されてしまう可能性があります。

これを防ぐための機能が、前述でも少し触れた下記ページの validation 機能になります。この機能を利用することで、思わぬ値に変更されることを防ぐ事が可能です。

validationの解説ページアイキャッチTkinterの使い方:validation機能の使い方(エントリーウィジェットの拡張)

ですが、上記ページを読んでいただければわかるとおり、validation 機能を利用するのもそれなりに手間がかかります。また、これも少し前述で触れましたが、少なくとも私の環境だと validation 機能はうまく動作してくれませんでした…。

そんな時に便利なのが state="readonly" 指定で、これだけ指定してやれば上下ボタンでしかスピンボックスの値を変更できなくなるので、前述の from_to で指定した範囲の値 or values で指定したタプルに含まれる値しかスピンボックスに設定できなくなります。

思わぬ値が設定されないようにするのには、state="readonly" 指定するのが楽だと思います。

下記はスピンボックスウィジェットを読み取り専用状態に設定する例になります。

stateの指定例
spinbox = tkinter.Spinbox(
	app, # 親ウィジェット
	state="readonly"
)

takefocus

takefocus はタブキーによるフォーカスの有効無効を指定するオプションになります。

スピンボックスウィジェットにおいては、フォーカスをあてることでそのスピンボックウィジェットに対して文字列を入力することができるようになります。また、フォーカスがあたっている状態でキーボードの上下キーを押すことで、値を変化させることも可能です。

takefocus に指定可能なパラメータは下記のようになります。

  • True0):フォーカスを無効(フォーカスがあてられない)
  • False1):フォーカスを有効(フォーカスがあてられる)(デフォルト)

下記はスピンボックスウィジェットへのフォーカスを無効に指定する例になります。

takefocusの指定例
spinbox = tkinter.Spinbox(
	app, # 親ウィジェット
	takefocus=False
)

format

format はスピンボックスの値の表示桁数を指定するオプションになります。

formatオプションの説明図

format には "%全表示桁数.小数点以下の表示桁数f" の形式の文字列を指定します。

全表示桁数 には、小数点を1桁分として考えて指定を行う必要があります。

また、全桁数の前に 0 を付けることで、値を表示するのに整数部の桁が足りない場合に 0 埋めするように設定することも可能です。

さらに 全表示桁数 や .小数点以下の表示桁数 の部分は省略可能です。.小数点以下の表示桁数 を指定した場合、小数点以下の表示桁数は6桁になります。

例えば、スピンボックスの値が 0 である時、format="%6.2f" を指定していれば __0.00 がスピンボックスの値として表示されることになります(_ は空白文字を示しています。フォントが等幅フォントでない場合、空白文字は非常に小さく表示される可能性があるので注意してください)。

また、format="%06.2f" に変更すれば、000.00 がスピンボックスの値として表示されることになります。

さらに、format="%06.0f" に変更すれば、000000 がスピンボックスの値として表示されることになります。

下記はスピンボックスウィジェットの値の全表示桁数を 6 桁に、小数点以下の表示桁数を 2 桁に指定する例になります(全表示桁数には小数点の1桁が含まれます)。

formatの指定例
spinbox = tkinter.Spinbox(
	app, # 親ウィジェット
	format="%6.2f"
)

スポンサーリンク

font

font はスピンボックス上の文字のフォントを指定するオプションになります。また、このフォントのサイズに応じてスピンボックスの上下ボタンの大きさも変化することになります。

fontオプションの説明図

font にはフォントの情報を格納したタプルや tkinter.font.Font クラスのインスタンスを指定することができます。フォントの指定方法の詳細は下記ページで解説していますので、詳しく知りたい方は下記ページを参考にしていただければと思います。

フォント指定解説ページのアイキャッチTkinterの使い方:フォントの指定方法

下記はスピンボックスウィジェットの文字のサイズを 40 に指定する例になります。

fontの指定例
spinbox = tkinter.Spinbox(
	app, # 親ウィジェット
	font=("", 40)
)

fg(or foreground

fg は、通常状態時および読み取り専用状態時のスピンボックスの文字の色および上下ボタンの矢印の色を指定するオプションになります。foreground も全く同じ意味のオプションになります。

fgオプションの説明図

fgforeground にはカラーコードや色名を指定します。

無効状態時の文字の色や上下ボタンの矢印の色を指定するのは disabledforeground になります。

下記はスピンボックスウィジェットの文字の色と上下ボタンの矢印の色を "red" に指定する例になります。

fgの指定例
spinbox = tkinter.Spinbox(
	app, # 親ウィジェット
	fg="red"
)

bg(or background

bg は、通常状態時のスピンボックスの背景色を指定するオプションになります。background も全く同じ意味のオプションになります。

bgオプションの説明図

bgbackground にはカラーコードや色名を指定します。

より具体的にいうと、この bg および background は、スピンボックスウィジェットにおける下記の3つを除いた全ての部分の色を設定するオプションになります。

  • 文字の色
  • 上下ボタンの矢印の色
  • 上下ボタンの背景の色

前者2つの色に関しては fg によって指定され、さらに3つ目に関しては次に紹介する buttonbackground によって色が指定されます。

また、bg および background で設定できるのはあくまでも通常状態時の背景色になります。無効状態時の背景色を指定するオプションは disabledbackground になりますし、読み取り専用状態時の背景色を指定するオプションは readonlybackground になります。

下記はスピンボックスウィジェットの通常状態時の背景色を "blue" に指定する例になります。

bgの指定例
spinbox = tkinter.Spinbox(
	app, # 親ウィジェット
	bg="blue"
)

スポンサーリンク

buttonbackground

buttonbackground は、スピンボックスの上下ボタンの背景色を指定するオプションになります。

buttonbackgroundオプションの説明図

buttonbackground にはカラーコードや色名を指定します。

状態に関わらず、スピンボックスの上下ボタンの背景色は常に、この buttonbackground で指定する色に設定されるようです。

下記はスピンボックスウィジェットの上下ボタンの背景色を "green" に指定する例になります。

buttonbackgroundの指定例
spinbox = tkinter.Spinbox(
	app, # 親ウィジェット
	buttonbaciground="green"
)

buttonupreliefbuttondownrelief

buttonuprelief はスピンボックスの上ボタンの見た目を、buttondownrelief はスピンボックスの下ボタンの見た目を指定するオプションになります。

buttonupreliefオプションとbuttondownreliefオプションの説明図

スピンボックス全体の見た目を変更したい場合は、relief で解説している relief オプションを指定してください。

buttonuprelief および buttondownrelief に指定可能なパラメータは下記の6つになります。

  • tkinter.RAISED
  • tkinter.SUNKEN
  • tkinter.FLAT
  • tkinter.RIDGE
  • tkinter.GROOVE
  • tkinter.SOLID

例えば tkinter.RAISED を指定すればボタンを浮き上がるような見た目に、tkinter.SUNKEN を指定すればボタンが沈み込むような見た目に変化させる事ができます。

ただし、こういった relief 関連のオプションにおいては、relief オプションを指定する部品を囲む枠線が太ければ太いほど強調されて見た目が変化することになります。

スピンボックスの上ボタンや下ボタンに関しては枠線の太さが非常に細いので、buttonuprelief や buttondownrelief を指定したところでほぼ見た目は変わらないようです(私の環境だと全く変わりませんでした…)。

下記はスピンボックスウィジェットの上ボタンの見た目を tkinter.SUNKEN に、下ボタンの背景色を tkinter.SOLID に指定する例になります。

ボタンのreliefの指定例
spinbox = tkinter.Spinbox(
	app, # 親ウィジェット
	buttonuprelief=tkinter.SUNKEN,
	buttondownrelief=tkinter.SOLID
)

buttocursor

buttoncursor は、スピンボックスの上下ボタン上にマウスカーソルが移動してきた時のカーソルの見た目(アイコン)を指定するオプションになります。

ボタン上だけでなく、スピンボックスウィジェット全体の上にマウスカーソルが移動してきた時のカーソルの見た目を変更したい場合は、cursor で解説している cursor オプションを指定してください。

例えば cursor には下記のような値を設定することが可能です。

  • "hand"
  • "ibeam"
  • "wait"
  • "poof"

OS 毎に指定可能な値が異なる可能性が高いので注意してください。

下記は上下ボタン上のマウスカーソルの見た目を "hand" に指定する例になります。

ボタンのreliefの指定例
spinbox = tkinter.Spinbox(
	app, # 親ウィジェット
	buttoncursor="hand"
)

スポンサーリンク

repeatdelayrepeatinterval

スピンボックスにおいては、上下ボタンを押し続けることで連続的に値を増減させる事が可能です。

repeatdelay は、ボタンを押し続けてから最初に値を増減させるまでの間隔の時間を、repeatinterval は、それ以降の値を増減させるまでの間隔の時間を指定するオプションになります。

repeatdelayrepeatinterval には間隔の時間を整数で指定します(単位はミリ秒となります)。

例えば下のアニメは、repeatdelay=10repeatinterval=500 と指定して作成したスピンボックスの上ボタンを押し続けた時の動作になります(ボタンを押している間マウスカーソルの周りに円が表示されます)。

repeatdelayオプションとrepeatintervalオプションの説明アニメ1

ボタンを押し始めて 10 ミリ秒経過した後に値が増加し、その後は 500 ミリ秒間隔で値が増加していきます。

今度は、repeatdelay=1000repeatinterval=5 と指定して作成したスピンボックスの上ボタンを押し続けた時の動作を下のアニメとして示します。

repeatdelayオプションとrepeatintervalオプションの説明アニメ2

ボタンを押し始めて 1000 ミリ秒経過した後に値が増加し、その後は 5 ミリ秒間隔で値が増加していきます。

こんな感じで、ボタンを押し続けた時の値の変化する間隔を指定するのが、repeatdelayrepeatinterval オプションになります。

スピンボックスのメソッド

次はスピンボックスウィジェット(tkinter.Spinbox クラス)に用意された、このウィジェット特有のメソッドについて解説していきます。

オプション同様に、下記ページで紹介しているエントリーウィジェットと同じメソッドが多く用意されています。

エントリーウィジェットの説明ページアイキャッチTkinterの使い方:エントリー(Entry)の使い方

下記に関しては全く同じメソッドになりますので、これらのメソッドについて知りたい場合は、エントリーウィジェットの方のメソッドの解説を参照していただくようお願いいたします(メソッド名にリンクを貼っていますので、クリックすればエントリーウィジェットに対する解説が表示されるようになっています)。

MEMO

エントリーウィジェットの場合、上記の selection_ で始まるメソッドは全て、メソッド名を select_ で始まるように変更して実行しても同様の動作をさせる事が可能です(例えば selection_clearselect_clear でも実行可能)

ただし、スピンボックスウィジェットの場合は、select_ から始まるメソッドは用意されていませんので注意してください(例えば select_clear を実行するとエラーになるので、必ず selection_clear を使う必要がある)

このページでは、上記で挙げたメソッドを除いた下記のメソッドについて解説していきます。

invoke

invoke はスピンボックスの上下ボタンのクリックと同様の操作をスクリプトから実行するメソッドです。

invoke
invoke(self, element)

element には下記の3つのいずれかの文字列を指定します。

  • "buttonup"
  • "buttondown"
  • "none"

element に "buttonup" を指定して invoke メソッドを実行した場合、マウスで上ボタンをクリックしたときと同様の処理が実行されます。

より具体的には、スピンボックスの値が増加し、さらに command オプションが指定されている場合、command オプションに指定されている関数が実行されることになります。

同様に、element に "buttondown" を指定して invoke メソッドを実行した場合は、マウスで下ボタンをクリックしたときと同様の処理が実行されます。

element に "none" を指定して invoke メソッドを実行することも可能ですが、この場合は何も処理が行われないようです(なので使い道はちょっと不明ですね…)。

例えば下記は、ボタンウィジェットをクリックすることで、スピンボックスウィジェットの上ボタンをクリックしたときと同様の処理を行うようにするための invoke メソッドの使用例となります。

invokeメソッドの使用例
# -*- coding:utf-8 -*-
import tkinter

def button_func():
	# 上ボタンを押したときと同様の処理を実行
	spinbox.invoke("buttonup")

app = tkinter.Tk()

# スピンボックスウィジェットの作成と配置
spinbox = tkinter.Spinbox(
	app,
	from_=0,
	to=255,
)
spinbox.pack(padx=10, pady=10)

button = tkinter.Button(
	app,
	text="上ボタン",
	command=button_func
)
button.pack(padx=10, pady=10)

app.mainloop()

スポンサーリンク

index

index は引数に対応した位置(を表す数値)を返却値として取得するメソッドになります。

index
index(self, index)

引数 index に指定可能なパラメータと、それを指定してメソッドを実行した時に得られる位置は下記のようになります。

  • tkinter.END:最後の文字の次の位置(つまり、スピンボックスの値の文字数)
  • tkinter.INSERT:挿入カーソルが存在する位置
  • tkinter.ANCHOR:最後にクリックした位置
  • tkinter.SEL_FIRST:選択範囲の先頭の位置
  • tkinter.SEL_LAST:選択範囲の末尾の位置

例えば下図のような状態で index メソッドを実行した場合(選択は、c の直前の位置でクリックしたのちにドラッグ操作で g までを選択しています)、

indexメソッドの動作を説明するための図

各パラメータそれぞれで得られる値は下記のようになります。

  • tkinter.END10
  • tkinter.INSERT2
  • tkinter.ANCHOR2
  • tkinter.SEL_FIRST2
  • tkinter.SEL_LAST7

エントリーウィジェットの値が選択されていない状態で tkinter.SEL_FIRSTtkinter.SEL_LAST を引数に指定して index メソッドを実行すると tkinter.TclError が発生するので注意してください。tkinter.SEL_FIRSTtkinter.SEL_LAST を引数に指定して index メソッドを実行するのであれば、例外処理を行なっておいた方が無難だと思います。

下記は、上記で紹介したパラメータそれぞれに対応する位置を表示する際の、index メソッドの使用例になります。

indexメソッドの使用例
# spinboxはtkinter.Spinboxクラスのインスタンス
print(spinbox.index(tkinter.END))
print(spinbox.index(tkinter.INSERT))
print(spinbox.index(tkinter.ANCHOR))

try:
	print(spinbox.index(tkinter.SEL_FIRST))
	print(spinbox.index(tkinter.SEL_LAST))
except tkinter.TclError:
	print("スピンボックスの値が選択されていません")

bbox

bbox は指定した位置に表示されている文字の座標情報(位置やサイズ)を取得するメソッドになります。

bbox
bbox(self, index)

bbox メソッドの引数 index には、座標情報を取得したい文字の位置を指定します(先頭を 0 文字目として、先頭から何文字目かを指定する)。

bbox メソッドの戻り値が、その文字が表示されている座標の情報を示すタプルとなります。

このタプルは下記の形式のものになります。

(x, y, width, height)

それぞれの値の意味は下記の通りです(単位は全てピクセル・原点はスピンボックスの左上座標)。

  • x:その文字の左上の横方向の座標
  • y:その文字の左上の縦方向の座標
  • width:その文字の幅
  • height:その文字の高さ
    bboxメソッドの返却値の各要素の意味を示す図

例えば下記は、先頭から3 文字目の位置の文字が表示されている座標を取得する際のbbox メソッドの使用例になります(先頭の文字は 0 文字目としてカウント)。

bboxの使用例
# spinboxはtkinter.Spinboxクラスのインスタンス
print(spinbox.bbox(3))

上記では引数を即値で指定していますが、index で紹介した tkinter.INSERT 等のパラメータを指定しても良いです。

identify

identify は、引数で指定した座標にスピンボックスウィジェットのどの部品が存在するかを取得するメソッドになります。

identify
identify(self, x, y)

引数で指定される (x, y) 座標に存在するスピンボックスウィジェットの部品に応じて、identify メソッドは下記の文字列を返却します。

  • "entry":(x, y) 座標にスピンボックスのエントリー部が存在する場合
  • "buttonup":(x, y) 座標にスピンボックスの上ボタンが存在する場合
  • "buttondown":(x, y) 座標にスピンボックスの下ボタンが存在する場合
  • "":(x, y) 座標がスピンボックス上の座標でない場合

スポンサーリンク

selection_element

selection_element は、引数で指定した上下ボタンのいずれかを選択する、もしくは、現在選択されているボタンを取得するメソッドになります。

selection_element
selection_element(self, element=None)

正直使いどころを私も理解できていないメソッドになります…。とりあえず確認できた動作について記載しておきます。

まず引数 element を指定しなかった場合、すなわち引数なしでメソッドを実行した場合、現在選択中のボタンを文字列として取得することになります(element=None を指定してメソッドを実行した場合も同様の動作になります)。

取得できる文字列は、具体的には下記のようになります。

  • 上ボタンが選択されている場合:"buttonup"
  • 下ボタンが選択されている場合:"buttondown"
  • 上記のいずれかにも当てはまらない場合:"none"

その一方で、引数で element を指定した場合、element に指定したパラメータに応じてボタンが選択され、ボタンが押されたような見た目に変化します。

 element に指定できるパラメータは下記の3つになります。

  • "buttonup":上ボタンが選択される
  • "buttondown":下ボタンが選択される
  • "none":何も選択されない

まとめ

このページでは tkinter におけるスピンボックスウィジェットについて解説しました!

スピンボックスを使う際に最低限必要になるのは下記の処理になります。

  • スピンボックスウィジェットの作成と配置を行う
  • 適切なタイミングでスピンボックスの値を取得する(さらに、その値を他のウィジェットに反映する)

特に後者に関しては、スピンボックスの値の取得 で解説していますので、ここはしっかり理解しておくと良いと思います。

また、上下ボタンが押されたタイミングでスピンボックスの値を取得したい場合は command オプションを指定し、上下ボタンだけでなくエントリー部から値を直接変更されたタイミングでも他のウィジェットに変更後の値を反映したいような場合はウィジェット変数を利用するのが良いと思います。

スピンボックスウィジェットはエントリーに上下ボタンが追加されたようなウィジェットであり、エントリーの使い方と似ている部分もあるので、一緒に使い方を覚えておくと良いと思います!