このページでは、tkinter で作成したアプリを実行した際に発生するエラーの “原因” とその “対処法” をまとめています。
現状はまだ説明しているエラーの種類が少ないですが、私が実際にエラーに出くわした際に随時このページに加筆をしていこうと思います。
“エラーは発生していないのに” アプリがうまく動作してくれない時の対処法については下記ページにまとめていますので、これらを知りたい方は是非下記ページを読んでみていただければと思います。
【tkinter】アプリがうまく動作しない時の対処法まとめContents
ウィジェット作成・設定関連
まずはウィジェット作成時(ウィジェットのクラスのコンストラクタ実行時)やウィジェットの設定時(config メソッド実行時)に発生するエラーについて紹介していきます!
unknown option "-xxxx"
エラーが発生するスクリプト例
このエラーは下記のようなスクリプトを実行した際に発生します。
import tkinter
app = tkinter.Tk()
button1 = tkinter.Button(
app,
releif=tkinter.RAISED # ここでエラー
)
button1.grid()
app.mainloop()
原因
ウィジェット作成時(ウィジェットクラスのコンストラクタ実行時)やウィジェットの設定変更時(config
メソッド実行時)に発生するエラーです。
指定したオプション(キーワード)がそのウィジェットに用意されていない場合にこのようなエラーが発生します。
対処法
要は、ウィジェット作成時やウィジェットの設定変更時に、そのウィジェットに用意されているオプションを指定するようにすれば良いです。
各ウィジェットに用意されているオプションは、下記により確認することができます。
# "Widget"はウィジェットのクラス名に変更する
widget = tkinter.Widget(
# 略
)
print(widget.keys())
例えばボタンウィジェットで設定可能なオプションは、下記のように出力されます。
['activebackground', 'activeforeground', 'anchor', 'background', 'bd', 'bg', 'bitmap', 'borderwidth', 'command', 'compound', 'cursor', 'default', 'disabledforeground', 'fg', 'font', 'foreground', 'height', 'highlightbackground', 'highlightcolor', 'highlightthickness', 'image', 'justify', 'overrelief', 'padx', 'pady', 'relief', 'repeatdelay', 'repeatinterval', 'state', 'takefocus', 'text', 'textvariable', 'underline', 'width', 'wraplength']
設定しようとしたオプションが用意されていないのであれば「そのオプション指定を外す」、タイプミスしているのであれば「そのタイプミスを修正する」ことで、このエラーは解消することができると思います。
例えば前述のスクリプトであれば releif
がタイプミスになっているので、relief
に修正すればエラーが発生しなくなります。
スポンサーリンク
配置関連
次はウィジェットの配置時におけるエラーを紹介していきます。
cannot use geometry manager grid inside . which already has slaves managed by pack
エラーが発生するスクリプト例
このエラーは下記のようなスクリプトを実行した際に発生します。
import tkinter
app = tkinter.Tk()
button1 = tkinter.Button(
app,
text="ボタン1"
)
button1.pack()
button2 = tkinter.Button(
app,
text="ボタン2"
)
button2.grid() # ここでエラー
app.mainloop()
原因
原因は、同じ親ウィジェット上への配置に pack
と grid
を混在して使用していることです。
ウィジェットはコンストラクタを実行して作成しますが、その時の第1引数に指定するのが作成先の親ウィジェットです。
同一の親ウィジェットに作成したウィジェットを配置する際には、pack
と grid
を混在して使用することができません。どちらか一方に統一する必要があります(place
は混在可)。
対処法
このエラーの対処法は2つあります。
pack
とgrid
のどちらかに統一する- 親ウィジェットを別にする
pack
と grid
のどちらかに統一する
配置に用いるメソッドを pack
と grid
のどちらかに統一すればエラーは解決します。ただこれだと pack
と grid
を混在することができないので、実現したいアプリのレイアウトが実現できない場合があります。
親ウィジェットを別にする
どうしても pack
と grid
を混在したい場合は、pack
を使用したいウィジェットと grid
を使用したいウィジェットの親ウィジェットを別のものにすれば解決します。
前述で下記のような説明をしました。
同一の親ウィジェットに作成したウィジェットを配置する際には、
pack
とgrid
を混在して使用することができません。
これは “同一の親ウィジェット” にウィジェットを配置する時の話で、”異なる親ウィジェット” に作成したウィジェットにおいては pack
と grid
を混在することができます。
異なる親ウィジェットを用意するときに便利なのがフレームウィジェットです。
より具体的には、フレームを複数用意し、そのフレームを親ウィジェットとしてウィジェットを作成します。
これにより、フレーム内のウィジェットの配置を pack
か grid
のどちらかに統一さえすれば、フレーム間では pack
と grid
を混在させてウィジェットの配置を行うことができます。
フレームについては下記ページで解説していますので、詳しくはこちらのページをご参照ください。
Tkinterの使い方:フレームウィジェット(Frame)の使い方cannot use geometry manager pack inside . which already has slaves managed by grid
エラーが発生するスクリプト例
このエラーは下記のようなスクリプトを実行した際に発生します。
import tkinter
app = tkinter.Tk()
button1 = tkinter.Button(
app,
text="ボタン1"
)
button1.grid()
button2 = tkinter.Button(
app,
text="ボタン2"
)
button2.pack() # ここでエラー
app.mainloop()
原因
エラー文言が若干違うものの、エラーの原因の本質は cannot use geometry manager grid inside . which already has slaves managed by pack と同じです。
エラーの文言が異なるのは grid
と pack
の実行順序の違いによるものです。
grid
実行後に pack
を行なった場合は下記が表示され、
cannot use geometry manager pack inside . which already has slaves managed by grid<
pack
実行後に grid
を実行した場合は下記が表示されます。
cannot use geometry manager grid inside . which already has slaves managed by pack
対処法
対処法は、cannot use geometry manager grid inside . which already has slaves managed by packと同じです。
スポンサーリンク
イベント関連
続いてはイベント関連のエラーを紹介していきます。
TypeError: xxxx() takes 0 positional arguments but 1 was given
エラーが発生するスクリプト例
このエラーは下記のようなスクリプトを実行し、ボタンをクリックした際に発生します。
import tkinter
def click(): # ここでエラー
print("click")
app = tkinter.Tk()
button = tkinter.Button(
app,
text="ボタン"
)
button.pack()
button.bind("<ButtonPress>", click)
app.mainloop()
原因
関数の定義の引数の数と、関数に渡される引数の数が異なることが原因です。
別に tkinter 特有のエラーではないですが、イベントハンドラの呼び出し時に発生しやすいエラーなので紹介しています。
bind
で受付設定済みのイベントが発生した際には、Event
クラスのオブジェクトを引数としてイベントハンドラが実行されます。
したがって、イベントハンドラとなる bind
の第2引数に指定する関数は引数を1つは受け取れるように定義する必要があります。引数を受け取らないように関数定義をしてしまっていると、上記のようなエラーが発生することになります。
対処法
イベントハンドラに設定する関数(bind
の第2引数に指定する関数)を下記のように定義すれば問題は解決します。
def eventHandler_func(event):
もしイベントハンドラにクラスのメソッドを設定する場合は、下記のように定義すれば問題は解決します。
def eventHandler_method(self, event):
例えば前述のスクリプトであれば、bind で指定する click 関数を下記のように引数をとるように修正すればエラーが発生しなくなります。
def click(event):
bad event type or keysym "XxxxXxxx"
エラーが発生するスクリプト例
このエラーは下記のようなスクリプトを実行した際に発生します。
import tkinter
def click(event):
print("click")
app = tkinter.Tk()
button = tkinter.Button(
app,
text="ボタン"
)
button.pack()
button.bind("<ButtonPush>", click) # ここでエラー
app.mainloop()
原因
このエラーが発生する原因は「イベントシーケンス(bind
メソッドの第1引数)の指定に不備がある」ことです。
イベントシーケンスについては下記ページで解説していますので、ご存知ない方はこちらをご参照いただければと思います。
Tkinterの使い方:イベント処理を行うイベントシーケンスに指定可能でないイベントタイプを指定してしまった時などにこのエラーは発生します。
例えば上記のスクリプトではイベントシーケンスのイベントタイプに ButtonPush
を指定していますが、このようなイベントタイプは存在しないので、エラーが発生してしまいます。
対処法
正しくイベントシーケンスを指定してやればこのエラーは解消します。
指定可能なイベントタイプなどについては下記ページで紹介していますし、
Tkinterの使い方:イベント処理を行うどんな時にどんなイベントが発生するかの調べ方は下記ページで解説していますので、このあたりを参考にしてイベントシーケンスを指定していただければ良いと思います。
Tkinter の使い方:利用可能なイベントやイベントが発生するタイミングを調べる例えば前述のスクリプトであれば、イベントシーケンスのイベントタイプとして ButtonPush
ではなく ButtonPress
に修正すればエラーが発生しなくなります。
スポンサーリンク
画像関連
今度は画像を扱うときによく発生するエラーを紹介します。
couldn't recognize data in image file "XXX.jpg"
エラーが発生するスクリプト例
このエラーは下記のようなスクリプトを実行した際に発生します(cat.jpg
はスクリプト実行ディレクトリに存在する前提です)。
import tkinter
app = tkinter.Tk()
image = tkinter.PhotoImage(
file="cat.jpg" # ここでエラー
)
canvas = tkinter.Canvas(
app,
width=400,
height=300
)
canvas.pack()
canvas.create_image(
0, 0,
image=image,
anchor=tkinter.NW
)
app.mainloop()
原因
このエラーは PhotoImage
クラスが対応していないフォーマットの画像を PhotoImage
クラスで扱おうとしている場合に発生します。
tkinter の PhotoImage
クラスが対応している画像フォーマットの種類は非常に少ないです。どの画像フォーマットに対応しているかは下記ページで紹介しています。
特にやりがちなのが JPEG ファイルの読み込みです。
JPEG も PhotoImage
は対応していないので、PhotoImage()
の file
引数で JPEG ファイルを指定するとエラーが発生します。
ちなみに、画像フォーマット関係なく file
に指定したファイルが存在しない場合は下記のエラーが発生します。
couldn't open "cat.jpg": no such file or directory
対処法
PhotoImage()
の file
引数に PNG などの PhotoImage
が対応している画像フォーマットのファイルを指定するようにすればエラーは解消します。
JPEG などの PhotoImage
が対応していない画像フォーマットのファイルがどうしても読み込みたい場合は、PIL や OpenCV などのモジュールを利用してファイルを読み込み、その読み込んだデータを tkinter の PhotoImage
クラスのオブジェクトに変換する方法がオススメです。
やり方の詳細は下記ページで解説していますので、詳しく知りたい方はこちらのページをご参照ください。
【Python】PIL ⇔ OpenCV2 ⇔ Tkinter 画像オブジェクトの相互変換まとめ
このページでは、tkinter で作成したアプリ実行時の “エラーの原因” とその “対処法” について解説しました!
いずれもエラーメッセージをしっかり読めばエラーの内容自体は把握できると思います。ただ、なぜエラーになるのかやどう対処すれば良いかについては疑問に思われる方もおられると思いますので、この辺りをまとめてみました!
まだ紹介しているエラーが少ないですが、紹介した方が良さそうなエラーを見つけ次第、随時このページに加筆していこうと思います。
ぜひエラーが発生して、その原因や対処法を知りたいときにこのページを参考にしてください!