このページでは「キャンバスウィジェットを作成する方法」について解説します。
キャンバスウィジェットへの図形の描画や描画した図形の操作については下記ページで解説していますので、特にキャンバスを利用したアプリ作成について知りたい方はこちらを読んでいただくと良いと思います。
Tkinterの使い方:Canvasクラスで図形を描画する Tkinterの使い方:Canvasクラスで描画した図形を操作するキャンバス
キャンバスは主に図形を描画するためのウィジェットになります。
tkinter ではキャンバスに対して下記のような図形を描画することができます。
- 長方形
- 多角形
- 楕円
- 円弧
- 線
- テキスト
- ビットマップ
- 画像
キャンバスの基本的な使い方
tkinter におけるキャンバスの基本的な使い方の流れは下記になります。
- メインウィンドウを作成する
- メインウィンドウにキャンバスを作成・配置する
- キャンバスに図形を描画する
- 描画した図形を操作する
特にキャンバスに深く関わるのが 2. 3. 4. の部分です。
下記がこの一連の使い方の流れを踏襲したスクリプト例になります。
# -*- coding:utf-8 -*-
import tkinter
def button_click():
global canvas
# 4. 描画した図形を操作する
color = canvas.itemcget(
"rectangle",
"fill"
)
if color == "blue":
canvas.itemconfig(
"rectangle",
fill="green"
)
else:
canvas.itemconfig(
"rectangle",
fill="blue"
)
# 1. メインウィンドウを作成する
app = tkinter.Tk()
# 2. メインウィンドウにキャンバスを作成・配置する
canvas = tkinter.Canvas(
app,
width=400,
height=300,
)
canvas.pack()
# 3. キャンバスに図形を描画する
canvas.create_rectangle(
50, 50, 300, 250,
fill="blue",
tag="rectangle"
)
# ボタンの作成と配置
button = tkinter.Button(
app,
text="ボタン",
command=button_click
)
button.pack()
# メインループ
app.mainloop()
このページでは特に「2. メインウィンドウにキャンバスを作成・配置する」についての解説になります。
「3. キャンバスに図形を描画する」に関しては下記ページで、
Tkinterの使い方:Canvasクラスで図形を描画する「4. 描画した図形を操作する」に関しては別途詳細を解説していますので、こちらについて知りたい方は是非リンクから目的のページに移動していただければと思います。
Tkinterの使い方:Canvasクラスで描画した図形を操作するスポンサーリンク
キャンバスウィジェットの作り方
キャンバスウィジェットは下記を実行することで生成することができます。
- Tkinter の
Canvas
クラスのインスタンスを生成する
キャンバスウィジェットを生成するスクリプト例は下記のようになります。
# -*- coding:utf-8 -*-
import tkinter
app = tkinter.Tk()
app.geometry("400x300")
# Canvas Widget
canvas = tkinter.Canvas(
app,
width=300,
height=200,
bg="blue",
)
canvas.pack()
app.mainloop()
実行すると下の図のようにメインウィンドウの中に背景が青色の「キャンバスウィジェット」が表示されることが確認できると思います(見た目は OS 等により異なります)。
メインウィンドウの作成とメインループ
下記部分はメインウィンドウ作成時と同じものになります。
# -*- coding:utf-8 -*-
import tkinter
app = tkinter.Tk()
app.geometry("400x300")
# 略
app.mainloop()
メインウィンドウが何かわからない方は、下記ページで解説していますのでコチラも読んでみてください。
Tkinterの使い方:メインウィンドウを作成するTkinter ではメインウィンドウの上にウィジェットの作成や配置を行うことで GUI アプリを開発していきます。
さらに、そのウィジェットの作成や配置は、基本的に「メインウィンドウの作成〜メインループの前」の間に行います。
ですので、GUI アプリを作成する場合は、上記のスクリプトで行っているメインウィンドウの作成(および設定)とメインループ実行部分は毎回記述することになります。
キャンバスウィジェットの作成(Canvas()
)
キャンバスウィジェットを実際に作成しているのは下記になります。tkinter.Canvas
クラスのインスタンスを生成しており、これによりキャンバスウィジェットが作成されます。
# Canvas Widget
canvas = tkinter.Canvas(
app,
width=300,
height=200,
bg="blue",
)
第1引数に指定するのは、作成するラベルウィジェットを配置する親ウィジェットになります。
基本的に第1引数には下記を指定します(上記スクリプトではメインウィンドウ app
を指定している)。
- メインウィンドウ
- サブウィンドウ
- フレームウィジェット
キーワード引数でウィジェットの設定(オプション)を指定することも可能です。
キャンバスウィジェットの設定についてはキャンバスウィジェットの設定で解説します。
スポンサーリンク
キャンバスウィジェットの配置
下記ではキャンバスウィジェットの配置を行なっています。
canvas.pack()
ウィジェットは作成するだけでは画面に表示されません。
配置を行うことで画面に表示されます(厳密には配置した後に mainloop
を実行することで表示される)。
ウィジェットの配置については下記ページで解説していますので、詳しく知りたい方はコチラを読んでいただければと思います。
Tkinterの使い方:ウィジェットの配置(pack・grid・place)キャンバスウィジェットの設定
キャンバスウィジェットでは他のウィジェット同様に、コンストラクタ(tkinter.Canvas()
)にキーワード引数を指定することで様々な設定を行うことが可能です。
指定できるキーワード引数は下記になります。
width
height
background
(bg
)borderwidth
(bd
)state
cursor
relief
takefocus
highlightbackground
highlightcolor
highlightthickness
selectbackground
selectborderwidth
selectforeground
closeenough
offset
insertbackground
insertborderwidth
insertofftime
insertontime
insertwidth
confine
scrollregion
xscrollcommand
xscrollincrement
yscrollcommand
yscrollincrement
このページではこの中の「Stipple に関わる設定」「インサートカーソルの見た目に関わる設定」「スクロールに関わる設定」を除いて解説をしていきたいと思います。
前者2つについては「おそらく使いどころが少ない」&「私の環境で動作しない」ため説明を省略させていただきます。
ちなみに Stipple とは小さなドットで塗りつぶすことを言います
このドットの密度を変化させることでグラデーションのように見せることができます
白黒しか色が使えない場合などは有効ですが、現状はいろんな色が使用できるのが当たり前の時代ですので、おそらく使用する機会はほとんどありません
スクロールに関しては別途下記ページで解説していますので、詳しく知りたい方は下記ページを読んでみていただければと思います。
Tkinterの使い方:スクロールバー(Scrollbar)の使い方それでは各設定について解説していきます。
width
・height
width
・height
キーワード引数ではキャンバスウィジェットの幅と高さを設定することができます。
width
と height
はそれぞれピクセル単位で指定します。
width
と height
の設定例は下記のようになります。
# -*- coding:utf-8 -*-
import tkinter
app = tkinter.Tk()
app.geometry("400x300")
# Canvas Widget
canvas = tkinter.Canvas(
app,
width=300,
height=200
)
canvas.pack()
app.mainloop()
スポンサーリンク
background
(bg
)
background
キーワード引数ではキャンバスウィジェットの背景色を設定することができます。
この背景色は bg
でも設定することができます。
background
もしくは bg
にはカラーコードもしくは色の名前の文字列を指定します。
background
の設定例は下記のようになります。
# -*- coding:utf-8 -*-
import tkinter
app = tkinter.Tk()
app.geometry("400x300")
# Canvas Widget
canvas = tkinter.Canvas(
app,
width=300,
height=200,
background="blue"
)
canvas.pack()
app.mainloop()
borderwidth
(bd
)
borderwidth
キーワード引数ではキャンバスウィジェットの枠の太さを設定することができます。
この枠の太さは bd
でも設定することができます。
borderwidth
もしくは bd
にはピクセル単位で指定します。デフォルト設定は 0 です。
borderwidth
の設定例は下記のようになります。
# -*- coding:utf-8 -*-
import tkinter
app = tkinter.Tk()
app.geometry("400x300")
# Canvas Widget
canvas = tkinter.Canvas(
app,
width=300,
height=200,
background="blue",
borderwidth=20
)
canvas.pack()
app.mainloop()
キャンバスの枠は基本的に背景色と同じ色なので(次に説明する relief
を使うと背景と異なる色になる)ので、borderwidth
を設定してもパッと効果が分かりにくいです。
が、実際に図形を (0, 0) 座標に描画してみると borderwidth
の設定の効果がはっきりと分かります。
下図の左側は borderwidth
を設定せずにオレンジ色の長方形を (0, 0) 座標から描画した結果で、右側は borderwidth
を 20 に設定してオレンジ色の長方形を (0, 0) 座標から描画した結果になります。
同じ位置に同じ大きさの長方形を描画しているのですが、右側では枠が太くなった分、その枠に隠れて長方形サイズが小さく見えることが確認できると思います。
relief
relief
キーワード引数ではキャンバスウィジェットの見た目を設定することができます。
relief
に指定できるのは下記の6つになります。
tkinter.RAISED
tkinter.SUNKEN
tkinter.FLAT
(デフォルト設定)tkinter.RIDGE
tkinter.GROOVE
tkinter.SOLID
relief
の設定によって下図のようにキャンバスの見た目が変化します。
relief
の設定例は下記のようになります。
# -*- coding:utf-8 -*-
import tkinter
app = tkinter.Tk()
app.geometry("400x300")
# Canvas Widget
canvas = tkinter.Canvas(
app,
width=300,
height=200,
background="blue",
borderwidth=20,
relief=tkinter.RAISED
)
canvas.pack()
app.mainloop()
枠が無いと見た目が変わりませんので、relief
を設定する場合は borderwidth
も一緒に設定するようにしましょう。
スポンサーリンク
キャンバスの状態を設定する(state
)
state
キーワード引数ではキャンバスウィジェットの状態を設定することができます。
キャンバスで state
キーワードに指定できるのは下記の2つになります。
tkinter.NORMAL
(デフォルト設定)tkinter.DISABLED
tkinter.DISABLED
を設定すれば、キャンバスウィジェットを無効化することができます。
無効化すると具体的にどうなるのかというと、通常状態から下記の2点が変わります。
- 図形に設定したイベント処理が行われなくなる
- 図形が無効状態用の見た目に変更される
create_xxxx
メソッドにdisabledxxxx
設定をした見た目に変わる- 例えば通常状態の図形の背景色は
fill
に指定した色で表示されるが、無効状態の図形の背景色はdisabledfill
に指定した色で表示される
- 例えば通常状態の図形の背景色は
state
の設定例は下記のようになります。
# -*- coding:utf-8 -*-
import tkinter
def click_func(event):
print("長方形がクリックされました")
app = tkinter.Tk()
app.geometry("400x300")
# Canvas Widget
canvas = tkinter.Canvas(
app,
width=300,
height=200,
background="blue",
state=tkinter.DISABLED
)
canvas.pack()
canvas.create_rectangle(
0, 0,
100, 100,
fill="orange", # 通常状態の背景色
disabledfill="gray", # 無効状態の背景色
tag="rect"
)
canvas.tag_bind("rect", "<ButtonPress>", click_func)
app.mainloop()
上記スクリプトでは create_rectangle
メソッドで長方形を描画するときに fill="orange"
と disabledfill="gray"
を設定しています。
前者は通常状態(state=tkinter.NORMAL
)の長方形の色で、後者は無効状態(state=tkinter.DISABLED
)の長方形の色になります。
また create_rectangle
で描画した長方形がマウスでクリックされた時のイベント処理を tag_bind
メソッドにより設定しています。これにより長方形がクリックされれば “長方形がクリックされました” という文字列がコンソールに表示されるようになっています。
上記のスクリプトをそのまま実行すると、キャンバスが無効状態なので「長方形の色が "gray"
」であることと「クリックしても反応しない(イベント処理が行われない)」ことが確認できると思います。
一方、上記のスクリプトで state=tkinter.DISABLED
部分を削除して(もしくは state=tkinter.NORMAL
に置き換えて)実行すれば、「長方形の色が "orange"
」であることと「クリックすると “長方形がクリックされました” とコンソールに表示される(イベント処理が行われる)」ことが確認できると思います。
state
の設定だけでは効果は分かりにくいですが、上記のように disabledxxxx
の設定や tag_bind
メソッドによるイベント設定を行っておくと state
の効果が分かりやすいと思います。
ちなみに disabledxxxx
については下記ページで、
tag_bind
メソッドについては下記ページで紹介していますので、詳しく知りたい方はこれらのページも是非読んでみてください。
キャンバス上のマウスカーソルを変更する(cursor
)
cursor
キーワード引数ではキャンバス上に入った時のマウスカーソルの見た目を設定することができます。
cursor
キーワードに指定できる設定の一例は下記になります。
"hand"
"ibeam"
"wait"
"start"
"poof"
例えば cursor="hand"
と指定すれば、キャンバス上にマウスが移動した時のカーソルの見た目が “手” のようになります。
ただし cursor
に関しては OS 毎に指定可能な値が異なる可能性が高いので注意してください。
cursor
の設定例は下記のようになります。
# -*- coding:utf-8 -*-
import tkinter
app = tkinter.Tk()
app.geometry("400x300")
# Canvas Widget
canvas = tkinter.Canvas(
app,
width=300,
height=200,
background="blue",
cursor="hand"
)
canvas.pack()
app.mainloop()
キャンバスへのフォーカスを有効にする(takefocus
)
takefocus
キーワード引数に True
を設定することで、キャンバスウィジェットへのタブキーでのフォーカスを有効化することができます。
デフォルトは False
になっていて、タブキーでのキャンバスウィジットへのフォーカスは無効化されています。
takefocus
の設定例は下記のようになります。
# -*- coding:utf-8 -*-
import tkinter
app = tkinter.Tk()
app.geometry("400x300")
# Canvas Widget
canvas = tkinter.Canvas(
app,
width=300,
height=200,
background="blue",
takefocus=True
)
canvas.pack()
button = tkinter.Button(
app,
text="ボタン"
)
button.pack()
app.mainloop()
アプリを起動してタブキーを押すと、細い線がキャンバスウィジットを囲み、フォーカスがキャンバスウィジットに移ったことが確認できると思います(もしかしたら環境によっては線が表示されない場合などあるかもしれません)。
何回かタブキーを押せば、ボタンとキャンバスに対して交互にこの線が表示されると思います。
この細い線はフォーカスが当たっていることを示す線で、次から解説するhighlightcolor
・highlightbackground
・highlightthickness
はこのフォーカスが当たっていることを示す線の見た目を変更するための設定になります。
スポンサーリンク
highlightcolor
highlightcolor
キーワード引数ではフォーカスが当たっていることを示す線の色を設定することができます。
highlightcolor
にはカラーコードもしくは色の名前の文字列を指定します。
highlightcolor
の設定例は下記のようになります。
# -*- coding:utf-8 -*-
import tkinter
app = tkinter.Tk()
app.geometry("400x300")
# Canvas Widget
canvas = tkinter.Canvas(
app,
width=300,
height=200,
background="blue",
takefocus=True,
highlightcolor="orange"
)
canvas.pack()
button = tkinter.Button(
app,
text="ボタン"
)
button.pack()
app.mainloop()
takefocusr
の時同様にアプリを起動してタブキーでフォーカスを移動させると、キャンバスウィジットにフォーカスが当たっていることを示す線の色がオレンジ色になっていることが確認できると思います。
highlightbackground
highlightcolor
はフォーカスが当たっていることを示す線の色を設定するキーワードでしたが、highlightbackground
キーワード引数では逆にフォーカスが当たっていないことを示す線の色を設定することができます。
highlightbackground
にはカラーコードもしくは色の名前の文字列を指定します。
highlightbackground
の設定例は下記のようになります。
# -*- coding:utf-8 -*-
import tkinter
app = tkinter.Tk()
app.geometry("400x300")
# Canvas Widget
canvas = tkinter.Canvas(
app,
width=300,
height=200,
background="blue",
takefocus=True,
highlightcolor="orange",
highlightbackground="gray"
)
canvas.pack()
button = tkinter.Button(
app,
text="ボタン"
)
button.pack()
app.mainloop()
タブキーによるフォーカスの移動により、キャンバスを囲う線の色が変化することを確認できると思います。
highlightthickness
highlightthickness
キーワード引数ではフォーカスが当たっていることを示す線 or フォーカスが当たっていないことを示す線の太さを設定することができます。
単位はピクセルで設定します。
highlightthickness
の設定例は下記のようになります。
# -*- coding:utf-8 -*-
import tkinter
app = tkinter.Tk()
app.geometry("400x300")
# Canvas Widget
canvas = tkinter.Canvas(
app,
width=300,
height=200,
background="blue",
takefocus=True,
highlightcolor="orange",
highlightbackground="gray",
highlightthickness=20
)
canvas.pack()
button = tkinter.Button(
app,
text="ボタン"
)
button.pack()
app.mainloop()
スポンサーリンク
selectbackground
これは主にキャンバスウィジットに描画したテキストに対する設定になります。
キャンバスウィジットに描画したテキストは下記のメソッドを用いることで特定の範囲を選択することができます。
select_from
select_to
これらのメソッドについては下記ページでも解説しています。
Tkinterの使い方:Canvasクラスで描画した図形を操作するselectbackground
キーワード引数ではこの選択した範囲のテキストの背景色を設定することができます。
selectbackground
にはカラーコードもしくは色の名前の文字列を指定します。
selectbackground
の設定例は下記のようになります。
# -*- coding:utf-8 -*-
import tkinter
app = tkinter.Tk()
app.geometry("400x300")
# Canvas Widget
canvas = tkinter.Canvas(
app,
width=300,
height=200,
selectbackground="orange"
)
canvas.pack()
# テキスト描画
canvas.create_text(
150, 100,
text="tkinter",
font=("",40),
tag="text"
)
# テキスト選択
canvas.select_from("text", 2)
canvas.select_to("text", 4)
app.mainloop()
selectforeground
selectforeground
キーワード引数では選択した範囲のテキストの文字の色を設定することができます。
selectforeground
にはカラーコードもしくは色の名前の文字列を指定します。
selectforeground
の設定例は下記のようになります。
# -*- coding:utf-8 -*-
import tkinter
app = tkinter.Tk()
app.geometry("400x300")
# Canvas Widget
canvas = tkinter.Canvas(
app,
width=300,
height=200,
selectbackground="orange",
selectforeground="red"
)
canvas.pack()
# テキスト描画
canvas.create_text(
150, 100,
text="tkinter",
font=("",40),
tag="text"
)
# テキスト選択
canvas.select_from("text", 2)
canvas.select_to("text", 4)
app.mainloop()
selectborderwidth
selectborderwidth
キーワード引数では選択した範囲を囲う線の太さを設定することができます。
selectborderwidth
はピクセル単位で指定します。
selectborderwidth
の設定例は下記のようになります。
# -*- coding:utf-8 -*-
import tkinter
app = tkinter.Tk()
app.geometry("400x300")
# Canvas Widget
canvas = tkinter.Canvas(
app,
width=300,
height=200,
selectbackground="orange",
selectforeground="red",
selectborderwidth=5
)
canvas.pack()
# テキスト描画
canvas.create_text(
150, 100,
text="tkinter",
font=("",40),
tag="text"
)
# テキスト選択
canvas.select_from("text", 2)
canvas.select_to("text", 4)
app.mainloop()
スポンサーリンク
closeenough
closeenough
キーワード引数では、キャンバス上に描画した図形に対してどれくらいマウスが近づいたらその図形にマウスインされたことにするかの度合いを設定することができます。
closeenough
に 1 を超える値を設定することで、描画した図形にある程度近づければ、図形上にマウスがあるとみなすことができるようになります。
closeenough
キーワード引数には実数(float)を指定します。
closeenough
の設定例は下記のようになります。
# -*- coding:utf-8 -*-
import tkinter
app = tkinter.Tk()
app.geometry("400x300")
# Canvas Widget
canvas = tkinter.Canvas(
app,
width=300,
height=200,
background="blue"
)
canvas.pack()
app.mainloop()
スクリプト内では長方形を描画しており、図形がアクティブになると(マウスが乗ると)色が赤色に変化するようにしています(create_rectangle
メソッドに activefill
を指定して設定)。
closeenough
を設定していないとマウスが実際に図形に乗らないと色が変わりませんが、上記のように closeenough
を設定するとマウスが実際に乗らなくてもマウスがある程度近づけば色が変わるようになります。
実際に上記スクリプトを実行してマウスを近づけたり遠ざけたりした時の動きは下のアニメのようになります。
キャンバスウィジット作成時の注意点
最後に私がキャンバスウィジットを使っていて困った点・注意点だと思ったことを記述しておきます(気付き次第追加していきます)。
キャンバスサイズがwidth
と height
設定と一致しない
width・height で解説したように、キャンバスのサイズは width
と height
キーワード指定により設定することができます。
ただし、width
と height
だけを設定した場合、実際のキャンバスウィジェットのサイズは width
と height
で設定した値よりも若干大きくなります。
これのせいで描画する図形の位置がずれる可能性があります。
サイズが width
・height
設定と一致しない例
例えば次のスクリプトはキャンバスウィジェット作成時に width=300
、height=200
と設定し、最後に winfo_width
・winfo_height
メソッドでキャンバスのサイズを取得するスクリプトです。
# -*- coding:utf-8 -*-
import tkinter
app = tkinter.Tk()
app.geometry("400x300")
# Canvas Widget
canvas = tkinter.Canvas(
app,
width=300,
height=200
)
canvas.pack()
# サイズ取得のために強制的にアップデート
canvas.update()
# サイズ表示
print("width = " + str(canvas.winfo_width()))
print("height = " + str(canvas.winfo_height()))
app.mainloop()
私の環境では実行すると下記のように表示されました。
width = 306 height = 206
サイズが width
と height
で設定した値と異なることが確認できると思います。
サイズが width
・height
設定と一致しない原因
width
と height
とキャンバスウィジェットのサイズが異なる理由は、枠のサイズが原因です。具体的には後に説明するフォーカスされていることを表す枠の太さ(highlightthickness
)が 0 でないためです。
サイズが width
・height
設定と一致させる解決策
この太さを 0 に設定すれば(Canvas()
に highlightthickness=0
を指定)、width
と height
とキャンバスウィジェットのサイズが一致するようになります。
# -*- coding:utf-8 -*-
import tkinter
app = tkinter.Tk()
app.geometry("400x300")
# Canvas Widget
canvas = tkinter.Canvas(
app,
width=300,
height=200,
highlightthickness=0
)
canvas.pack()
# サイズ取得のために強制的にアップデート
canvas.update()
# サイズ表示
print("width = " + str(canvas.winfo_width()))
print("height = " + str(canvas.winfo_height()))
app.mainloop()
borderwidth(bd)
が 0 でない場合も width
と height
とキャンバスウィジェットのサイズが一致しないことになりますので注意してください。
スポンサーリンク
まとめ
このページではキャンバスウィジェットの作成の仕方、キャンバスウィジェットの設定、キャンバスウィジェット作成時の注意点について解説しました。
キャンバスウィジェットは図形を描画するためのただのキャンバスですが、ウィジェット作成時に様々なキーワード指定により多くの設定を行うことができます。
これによりアプリの見た目をより自分好みのものに仕立てることができますので、どのような設定が可能かは是非覚えておいてください!