【tkinter】エラーが発生した時の対処法まとめ

tkinterのエラーの対処法まとめページのアイキャッチ

このページでは、tkinter で作成したアプリを実行した際に発生するエラーの “原因” とその “対処法” をまとめています。

現状はまだ説明しているエラーの種類が少ないですが、私が実際にエラーに出くわした際に随時このページに加筆をしていこうと思います。

“エラーは発生していないのに” アプリがうまく動作してくれない時の対処法については下記ページにまとめていますので、これらを知りたい方は是非下記ページを読んでみていただければと思います。

アプリがうまく動作しない時の対処法まとめページアイキャッチ【tkinter】アプリがうまく動作しない時の対処法まとめ

ウィジェット作成・設定関連

まずはウィジェット作成時(ウィジェットのクラスのコンストラクタ実行時)やウィジェットの設定時(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()

原因

原因は、同じ親ウィジェット上への配置に packgrid を混在して使用していることです。

ウィジェットはコンストラクタを実行して作成しますが、その時の第1引数に指定するのが作成先の親ウィジェットです。

同一の親ウィジェットに作成したウィジェットを配置する際には、packgrid を混在して使用することができません。どちらか一方に統一する必要があります(place は混在可)。

対処法

このエラーの対処法は2つあります。

  • packgrid のどちらかに統一する
  • 親ウィジェットを別にする
packgrid のどちらかに統一する

配置に用いるメソッドを packgrid のどちらかに統一すればエラーは解決します。ただこれだと packgrid を混在することができないので、実現したいアプリのレイアウトが実現できない場合があります。

親ウィジェットを別にする

どうしても packgrid を混在したい場合は、pack を使用したいウィジェットと grid を使用したいウィジェットの親ウィジェットを別のものにすれば解決します。

前述で下記のような説明をしました。

同一の親ウィジェットに作成したウィジェットを配置する際には、packgrid を混在して使用することができません。

これは “同一の親ウィジェット” にウィジェットを配置する時の話で、”異なる親ウィジェット” に作成したウィジェットにおいては packgrid を混在することができます。

異なる親ウィジェットを用意するときに便利なのがフレームウィジェットです。

より具体的には、フレームを複数用意し、そのフレームを親ウィジェットとしてウィジェットを作成します。

これにより、フレーム内のウィジェットの配置を pack か grid のどちらかに統一さえすれば、フレーム間では packgrid を混在させてウィジェットの配置を行うことができます。

フレームを分けることで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 と同じです。

エラーの文言が異なるのは gridpack の実行順序の違いによるものです。

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 関数を下記のように引数をとるように修正すればエラーが発生しなくなります。

修正後の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 クラスが対応している画像フォーマットの種類は非常に少ないです。どの画像フォーマットに対応しているかは下記ページで紹介しています。

Tkinterで画像を扱う方法の解説ページアイキャッチTkinter の使い方:PhotoImage・BitmapImageクラスで画像を扱う

特にやりがちなのが 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 で作成したアプリ実行時の “エラーの原因” とその “対処法” について解説しました!

いずれもエラーメッセージをしっかり読めばエラーの内容自体は把握できると思います。ただ、なぜエラーになるのかやどう対処すれば良いかについては疑問に思われる方もおられると思いますので、この辺りをまとめてみました!

まだ紹介しているエラーが少ないですが、紹介した方が良さそうなエラーを見つけ次第、随時このページに加筆していこうと思います。

ぜひエラーが発生して、その原因や対処法を知りたいときにこのページを参考にしてください!

コメントを残す

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