このページでは「キャンバスウィジェットを作成する方法」について解説します。
キャンバスウィジェットへの図形の描画や描画した図形の操作については下記ページで解説していますので、特にキャンバスを利用したアプリ作成について知りたい方はこちらを読んでいただくと良いと思います。
キャンバス
キャンバスは主に図形を描画するためのウィジェットになります。

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. キャンバスに図形を描画する」に関しては下記ページで、
「4. 描画した図形を操作する」に関しては別途詳細を解説していますので、こちらについて知りたい方は是非リンクから目的のページに移動していただければと思います。
スポンサーリンク
キャンバスウィジェットの作り方
キャンバスウィジェットは下記を実行することで生成することができます。
- 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 ではメインウィンドウの上にウィジェットの作成や配置を行うことで GUI アプリを開発していきます。
さらに、そのウィジェットの作成や配置は、基本的に「メインウィンドウの作成〜メインループの前」の間に行います。
ですので、GUI アプリを作成する場合は、上記のスクリプトで行っているメインウィンドウの作成(および設定)とメインループ実行部分は毎回記述することになります。
キャンバスウィジェットの作成(Canvas())
キャンバスウィジェットを実際に作成しているのは下記になります。tkinter.Canvas クラスのインスタンスを生成しており、これによりキャンバスウィジェットが作成されます。
# Canvas Widget
canvas = tkinter.Canvas(
app,
width=300,
height=200,
bg="blue",
)
第1引数に指定するのは、作成するラベルウィジェットを配置する親ウィジェットになります。
基本的に第1引数には下記を指定します(上記スクリプトではメインウィンドウ app を指定している)。
- メインウィンドウ
- サブウィンドウ
- フレームウィジェット
キーワード引数でウィジェットの設定(オプション)を指定することも可能です。
キャンバスウィジェットの設定についてはキャンバスウィジェットの設定で解説します。
スポンサーリンク
キャンバスウィジェットの配置
下記ではキャンバスウィジェットの配置を行なっています。
canvas.pack()
ウィジェットは作成するだけでは画面に表示されません。
配置を行うことで画面に表示されます(厳密には配置した後に mainloop を実行することで表示される)。
ウィジェットの配置については下記ページで解説していますので、詳しく知りたい方はコチラを読んでいただければと思います。
キャンバスウィジェットの設定
キャンバスウィジェットでは他のウィジェット同様に、コンストラクタ(tkinter.Canvas())にキーワード引数を指定することで様々な設定を行うことが可能です。
指定できるキーワード引数は下記になります。
widthheightbackground(bg)borderwidth(bd)statecursorrelieftakefocushighlightbackgroundhighlightcolorhighlightthicknessselectbackgroundselectborderwidthselectforegroundcloseenoughoffsetinsertbackgroundinsertborderwidthinsertofftimeinsertontimeinsertwidthconfinescrollregionxscrollcommandxscrollincrementyscrollcommandyscrollincrement
このページではこの中の「Stipple に関わる設定」「インサートカーソルの見た目に関わる設定」「スクロールに関わる設定」を除いて解説をしていきたいと思います。
前者2つについては「おそらく使いどころが少ない」&「私の環境で動作しない」ため説明を省略させていただきます。
ちなみに Stipple とは小さなドットで塗りつぶすことを言います
このドットの密度を変化させることでグラデーションのように見せることができます
白黒しか色が使えない場合などは有効ですが、現状はいろんな色が使用できるのが当たり前の時代ですので、おそらく使用する機会はほとんどありません
スクロールに関しては別途下記ページで解説していますので、詳しく知りたい方は下記ページを読んでみていただければと思います。
それでは各設定について解説していきます。
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.RAISEDtkinter.SUNKENtkinter.FLAT(デフォルト設定)tkinter.RIDGEtkinter.GROOVEtkinter.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_fromselect_to
これらのメソッドについては下記ページでも解説しています。
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 とキャンバスウィジェットのサイズが一致しないことになりますので注意してください。
スポンサーリンク
まとめ
このページではキャンバスウィジェットの作成の仕方、キャンバスウィジェットの設定、キャンバスウィジェット作成時の注意点について解説しました。
キャンバスウィジェットは図形を描画するためのただのキャンバスですが、ウィジェット作成時に様々なキーワード指定により多くの設定を行うことができます。
これによりアプリの見た目をより自分好みのものに仕立てることができますので、どのような設定が可能かは是非覚えておいてください!

