tkinter を Tcl/Tk を含めてステップ実行(デバッグ)する環境を構築

tkinterのステップ実行を行う方法の解説ページアイキャッチ

このページでは、特に MacOSX での VSCode 上で Python 標準ライブラリである tkinter を Tcl/Tk を含めて(さらには _tkinterも)ステップ実行する環境を構築する方法について解説していきたいと思います。

tkinter のステップ実行

まずは tkinter のステップ実行するメリットやステップ実行する環境を構築するまでの流れを解説していきます。

tkinter をステップ実行するメリット

tkinter や OpenCV 等の外部ライブラリが意図通りに動作してくれない時、その外部ライブラリをステップ実行できると便利です。

プログラムを一行ずつ停止させ、さらに変数の中身を確認しながらプログラムの動きを確認できるので、意図通りに動作してくれない理由(引数や使い方の何が問題か)を特定しやすいです。

例えば OpenCV をステップ実行する方法について下記で解説しています。

PythonとOpenCVの混合デバッグ方法解説ページのアイキャッチVSCode で Python と OpenCV を混合でデバッグ(ステップ実行)する方法!

tkinter も同様にステップ実行することが可能です。

スポンサーリンク

ステップ実行環境は tkinter だけでは不十分 

tkinter は Python スクリプトですので、下記ページのように launch.json に下記の justMyCode 設定を false にしてやれば、それだけで tkinter をステップ実行することが可能です。

外部モジュールも含めてデバッグする方法の解説ページアイキャッチ【Python】VSCode で外部モジュール・外部ライブラリも含めてデバッグする方法

ただし、tkinter の動きを理解したいのであれば Tcl/Tk も一緒にステップ実行できるようにすることをお勧めします。

tkinter は下記のように _tkinter、Tcl/Tk(さらには Tcl/Tk は Xlib というモジュールを利用する)が連携して動作することで機能を実現しています。

Pythonスクリプト -> tkinter -> _tkinter -> Tcl/Tk

各モジュールの簡単な役割と、記述されているプログラミング言語は下記のようになります。

  • tkinter(Python):Python で GUI アプリを開発するためのモジュール
  • _tkinter(C言語):Tcl/Tk のラッパーモジュール(tkinter と Tk & Tcl の繋ぎ目)
  • Tcl / Tk(C言語 / Tcl):ウィジェット等を提供するモジュール
    • さらには Xlib を利用してスクリーン上にそのウィジェット を表示する

tkinter や _tkinter はほぼ Tcl/Tk の関数を呼び出すだけの作りになっています。ですので、tkinter や _tkinter のみをステップ実行できたとしても実はあまり意味はありません。

おそらく、tkinter 利用時にエラーが発生したとしても、tkinter・_tkinter のみのステップ実行だけでは原因の探りようがないと思います。なぜならエラー処理の大半も Tcl/Tk で行われているからです。

じっくり tkinter の動きを確認してみたいのであれば、Tcl/Tk まではステップ実行できるようにした方が良いと思います。

ですので、このページでは tkinter の動きをさらに深く理解するためにも _tkinter、Tcl/Tk をステップ実行するための手順について解説していきたいと思います(tkinter に関しては前述の通り launch.json の変更だけでステップ実行可能ですので、このページでの説明は省略します)。

特にこのページでは、MacOSX 上で VSCode を用いてステップ実行する手順を解説します。

もし環境が異なる場合でも、ステップ実行するために必要な手順は同様ですので、自身の環境に置き換えて考えれば、ステップ実行する環境の構築の手助けになると思います。

tkinter をステップ実行する環境を構築する流れ

まずは tkinter をステップ実行する環境を構築する流れをざっくり説明します。

tkinter といっても、前述の通り実際に環境を構築するのは _tkinter と Tcl/Tk になります。

環境を構築する流れは下記のようになります。

  • Tcl/Tk のビルド
  • _tkinter のビルド
  • 動作確認

Tcl/Tk のビルド

ステップ実行できるように、まずは Tcl/Tk のソースコードをダウンロードし、デバッグ情報付きでビルドします。

Tcl/Tk は大きく分けると Tcl モジュールと Tk モジュールに分けられます。それぞれに対してビルドを行う必要があります。

これにより Tcl/Tk のステップ実行を行うことが可能になります。

_tkinter のビルド

さらに、自身でビルドした Tcl/Tk ライブラリを使用する _tkinter をビルドします。この時にもソースコードをダウンロードし、デバッグ情報付きでビルドを行います。

これにより _tkinter のステップ実行を行うことが可能になります。

さらに Python スクリプトで記述された tkinter をステップ実行できるように、VSCode の実行構成である launch.json を編集します。

これにより tkinter のステップ実行を行うことが可能になります。

_tkinter と Tcl/Tk はC言語でプログラミングされていますので、C言語ソースコードを make コマンドでビルドできたり、C言語プログラムをデバッグできる環境も必要になります。

これらについては OpenCV デバッグ方法のページで解説していますので、下記ページで情報を補完しながら環境構築をしていただければと思います(OpenCV は C++ でプログラミングされていますが、全く同じ方法で環境を構築できるはずです)。

PythonとOpenCVの混合デバッグ方法解説ページのアイキャッチVSCode で Python と OpenCV を混合でデバッグ(ステップ実行)する方法!

以上により、Python スクリプトを実行した際に Tcl/Tk まで入り込んでステップ実行することができるようになります。

動作確認

最後に動作確認を行ってしっかりステップ実行できることを確認しましょう!

ステップ実行(デバッグ)するための準備は下記ページ解説したのと同様の手順により行うことができます。

PythonとOpenCVの混合デバッグ方法解説ページのアイキャッチVSCode で Python と OpenCV を混合でデバッグ(ステップ実行)する方法!

このページでは特に、ステップ実行できているかどうかを確認するために「どこにブレークポイント」を設定すれば良いかについて解説したいと思います。

Tcl のビルド

それでは実際に tkinter をステップ実行する環境を構築する手順を解説していきたいと思います。

まずは Tcl/Tk の Tcl をビルドしていきます。

スポンサーリンク

Tcl のソースコードをダウンロード

Tcl のソースコードは下記サイトからダウンロードできます。

http://www.tcl.tk/software/tcltk/download.html

アクセスすると下記のようなダウンロードリンクが表示されますので、Tcl のダウンロードしたいバージョン&圧縮形式(tar.gz もしくは zip)のリンクをクリックします。

Tcl/Tkのソースコードのダウンロード

ページが移動し、しばらくするとダウンロードが自動的に実行されると思います。

Tcl のビルド設定

続いて Tcl のビルドの設定を行います。ここでデバッグ情報を生成するようにビルドの設定を行うことが重要です。

configure ファイルのあるフォルダに移動 

ビルドの設定は configure を実行することで行うことができます。

ダウンロードした tar.gz もしくは zip を展開すると、おそらく下の図のようなファイルやフォルダがあると思います。

tclフォルダの中身

ターミナルアプリからこのフォルダの中にある macosx フォルダに移動しましょう。そこに configure ファイルがあるはずです。

macosx フォルダに移動するのはあくまで MacOSX ユーザーの方のみです。例えば Windows を利用している方は win フォルダに移動します。

この configure を実行することで、MacOSX 向けに Tcl のビルドの設定を行うことが可能です。

configure の実行

configure にはオプションを指定することで、詳細な Tcl のビルドの設定を行うことが可能です。

今回目的としているステップ実行するためには、デバッグ情報を生成する必要があります。このデバッグ情報を生成するためには、オプション「--enable-symbols」を指定します。

具体的には、ターミナル等から下記コマンドを実行することで、Tcl をデバッグ情報付きでビルドするための設定を行うことができます。

./configure --enable-symbols

Tcl のビルド

configure の実行が終わると、configure で指定したオプションに基づいて Makefile が同じフォルダに生成されます。

あとは make コマンドを実行すれば、Tcl の各ソースコードが自動的にコンパイルされ、ライブラリファイルが生成されます。

make

スポンサーリンク

Tcl のインストール

make コマンドの実行によりC言語ソースコードから Tcl のライブラリ等が生成されます。最後にこのライブラリをインストールします。

インストールの実行

下記コマンドを実行することによりライブラリのインストールが行われます。

sudo make install

インストールの確認

MacOSX の場合、デフォルトだと Tcl のライブラリは下記フォルダにインストールされるはずです。

/Library/Frameworks/Tcl.framework/Versions/8.6/

8.6 の部分は Tcl のバージョンによって異なります。

このフォルダの中に「Tcl_debug」というファイルが生成されていれば Tcl のビルドとインストールは成功です。この Tcl_debug が Tcl のライブラリ本体になります。

また Tcl のライブラリのインストール先のフォルダには Headers フォルダが一緒にインストールされていると思います。

/Library/Frameworks/Tcl.framework/Versions/8.6/Headers

このフォルダには Tcl に関するヘッダーファイル(tcl.h など)が格納されています。

Tcl ライブラリのリネーム

最後に Tcl_debug のファイル名を Tcl にリネームしておいてください(おそらく既に Tcl というファイルがあるはずですので、先にその Tcl を他の場所に移動したりリネームしたりして退避しておいてください)。

これはのちにビルドする _tkinter からこのライブラリ Tcl を参照するための作業になります(もしかしたら _tkinter のビルド設定をうまくしてやればリネームは不要かも)。

Tk のビルド

次は Tcl/Tk の Tk をビルドしていきます。やることはほぼ Tcl と同じです。

Tk のソースコードをダウンロード

Tk のソースコードは Tcl 同様に下記サイトからダウンロードできます。

http://www.tcl.tk/software/tcltk/download.html

アクセスすると下記のようなダウンロードリンクが表示されますので、Tk のダウンロードしたいバージョン&圧縮形式(tar.gz もしくは zip)のリンクをクリックします。

Tcl/Tkのソースコードのダウンロード

ページが移動し、しばらくするとダウンロードが自動的に実行されると思います。

スポンサーリンク

Tk のビルド設定

続いて Tk のビルドの設定を行います。Tcl 同様に、ここでデバッグ情報を生成するようにビルドの設定を行うことが重要です。

また Tk の場合、Tk が使用する Tcl の設定が必要である点も注意が必要です。

configure ファイルのあるフォルダに移動 

Tcl の時と同様、ダウンロードしたファイルを展開し、ご自身の使用している OS に合わせて、ターミナルで configure ファイルの存在するフォルダに移動します。

MacOSX を利用しいるのであれば、macosx フォルダに移動すればオーケーです。

configure の実行

Tcl の時と同様に、configure 実行時にはデバッグ情報を生成するためにオプション「--enable-symbols」を指定することを忘れないようにしましょう。

Tk の configure 実行時には、もう一つ指定した方が良いオプションがあります。

それは「--with-tcl=パス」というオプションです。

Tk は Tcl を使用しますが、このオプションを指定することで、Tk にどの Tcl を使用させるかを設定することが可能です。

具体的には “パス” に tclConfig.sh というファイルが存在するフォルダのパスを指定します。

おそらく、Tcl のビルドで Tk ライブラリがインストールされたフォルダに tclConfig.sh も一緒にインストールされているはずですので、そのフォルダのパスを指定すれば良いはずです。

これにより Tk に Tcl のビルドでご自身がビルドした Tcl をTk に使用させることができます。

私の場合は Tcl のインストール時に下記フォルダに tclConfig.sh もインストールされましたので、このフォルダのパスを指定しました。

/Library/Frameworks/Tcl.framework/Versions/8.6/

configure 実行時に実行するコマンドの例は下記のようになります。

./configure --enable-symbols --with-tcl=/Library/Frameworks/Tcl.framework/Versions/8.6/

tclConfig.sh のインストール先のフォルダが上記とは異なる場合は、--with-tcl= に指定するパスを適宜修正していただければと思います。

Tk のビルド

Tcl と同様に、configure 実行後に下記コマンドを実行することで Tk をビルドすることができます。

make

Tk のインストール

これも Tcl 同様の作業になります。下記の3つを行ってください。

Tcl の時にやったことを Tk に置き換えて作業すれば良いだけです。

  • インストールの実行
  • インストールの確認
  • Tk のリネーム

スポンサーリンク

_tkinter のビルド

次は _tkinter のビルドを行います。

_tkinter は Python の標準ライブラリであり、Python 本体のソースコードと一緒に管理されており、Python 本体をビルドすれば同時に一緒に _tkinter もビルドされます。

Python 本体のビルドの方法は下記ページで解説していますので、こちらを参考にビルドしていただければと思います。

Python のビルド方法解説ページのアイキャッチPython をソースコードからビルドする

Python 本体ビルド時には使用する Tcl や Tk を設定することが可能です。これらの Tcl や Tk は Tcl のビルドTk のビルドであなた自身がビルドしたものを指定するようにする必要があります。

具体的には Tcl や Tk のヘッダーが存在するパスを --with-tcltk-includes で、Tcl や Tk のライブラリへのリンクの指定を –-with-tcltk-libs オプションで指定します。

私は configure 実行時に下記のようにオプションを指定してビルドを行いました。

./configure --prefix /Users/daeu/.pyenv/versions/3.10.0d --with-tcltk-includes="-I/Library/Frameworks/Tcl.framework/Versions/8.6/Headers -I/Library/Frameworks/Tk.framework/Versions/8.6/Headers" --with-tcltk-libs="-lm /Library/Frameworks/Tcl.framework/Versions/8.6/Tcl -lm /Library/Frameworks/Tk.framework/Versions/8.6/Tk" --with-pydebug

オプションで指定している各々のパスは、ご自身のフォルダ構成に合わせて変更してください。

動作確認

以上で _tkinter・Tcl/Tk をステップ実行するための準備は整ったといって良いです。

あとは実際に動かし、ステップ実行できるかどうかを確認してみましょう。

Python スクリプトの準備

まずはステップ実行できる環境が整っているかを確認するために、簡単な下記のスクリプトを準備しましょう。

動作確認用スクリプト
# -*- coding:utf-8 -*-
import tkinter

# メインウインドウを作成
app = tkinter.Tk()

# メインループ
app.mainloop()

スポンサーリンク

デバッグ環境・launch.json の準備

続いてデバッグ環境を準備します。

Tcl/Tk や _tkinter はC言語でプログラミングされていますので、これらをステップ実行する場合はC言語のデバッグ環境が必要になります。

また VSCode の場合、デバッグ開始時にどのような設定でデバッグするかを launch.json で設定してやる必要があります。

これらの準備の仕方は OpenCV のデバッグ方法を紹介している下記ページで解説していますので、こちらを参考にしていただければと思います。

PythonとOpenCVの混合デバッグ方法解説ページのアイキャッチVSCode で Python と OpenCV を混合でデバッグ(ステップ実行)する方法!

特に「C++ のデバッグ環境の作成」「VSCode の設定」「デバッグ実行」のあたりを読んでいただければデバッグする準備は整えられると思います。

ワークスペースには、_tkinter、Tcl/Tk の Tcl Tk の3つのモジュールならソースコードが含まれるように、フォルダの追加を行ってください(ビルドを行うためにダウンロードしたフォルダを追加してください)。

ワークスペースの設定

ブレークポイントの設定

次は _tkinter と Tcl/Tk のソースコードにブレークポイントを設定します。

上記スクリプトを実行すれば、必ず下記の関数が実行されます。

ですので、これらの関数の先頭部分にブレークポイントを設定した状態でデバッグ開始し、設定したブレークポイントで停止するかどうかでステップできる環境が整っているかどうかを確認できます。

  • cpython フォルダ/Modules/_tkinter.c の _tkinter_create_impl 関数
  • tk フォルダ/generic/tkWIndow.c の CreateTopLevelWindow 関数
  • tcl フォルダ/generic/tclNotify.c の Tcl_DoOneEvent 関数

デバッグ実行

最後にデバッグを開始し、ブレークポイントで設定した箇所で停止するかどうかを確認します。

実行時に使用する Python は自身でビルドして作成した Python である必要がある点に注意です。

上手く環境が準備できていれば、「続行」ボタン等でプログラムを進めると下記の順番で停止するはずです。

  1. _tkinter_create_impl
  2. CreateTopLevelWindow
  3. Tcl_DoOneEvent

例えば下の図は 1. の _tkinter_create_impl でプログラムが停止した時の様子になります。黄色の行の実行直前でプログラムが停止しています。

_tkinter_create_impl でプログラムが停止する様子

全てで停止した場合はステップ実行する環境の準備は万端です。いろんな箇所にブレークポインとを設定してプログラムを停止させ、ステップ実行しながら tkinter の動きを確認してみてください!

上手く停止してくれない場合は下記を確認すると良いと思います。

どこにも停止しない場合

どこにも停止しない場合は下記の2つを確認してみましょう。

  • 実行時に使用する Python が _tkinter のビルドでインストールしたものに設定されているか
  • _tkinter のビルド(Python のビルド)の configure 実行時に --with-pydebug オプションを指定しているか

_tkinter_create_impl のみ停止する場合

使用する Python の設定や _tkinter 自体のビルドは上手く出来ています。

この場合は下記の2つを確認してみましょう。

  • Tcl のビルドTk のビルドの configure 実行時に --enable-symbols オプションを指定しているか
  • _tkinter のビルド(Python のビルド)の configure 実行時に --with-tcltk-includes と  --with-tcltk-libs を指定しているか、またパスの指定先が間違っていないか

CreateTopLevelWindow もしくは  Tcl_DoOneEvent でのみ停止しない場合

この場合は Tcl と Tk のどちらかが上手くビルドできていない、もしくは Python(_tkinter) ビルド時に --with-tcltk-includes or  --with-tcltk-libs の指定がうまくいっていない可能性が高いです。

ですので、_tkinter_create_impl で停止しない場合同様に下記の2点を確認しましょう。

  • Tcl のビルドTk のビルドの configure 実行時に --enable-symbols オプションを指定しているか
  • _tkinter のビルド(Python のビルド)の configure 実行時に --with-tcltk-includes と  --with-tcltk-libs を指定しているか、またパスの指定先が間違っていないか

スポンサーリンク

まとめ

このページでは tkinter をステップ実行する方法について解説しました。

tkinter といっても、ウィジェットを表示したりイベント処理を行ったりするのは Tcl/Tk ですので、特に Tcl/Tk (&_tkinter)をステップ実行する方法に重点を置いて解説させていただきました。

ステップ実行できれば tkinter の動きを理解したり、tkinter がうまく動作してくれない場合でも、ステップ実行しながらその原因を探ることも可能になります。

tkinter の使い方をより詳しく理解したい方は、是非このページで紹介した方法でステップ実行する環境を構築してみてください!

ところどころ他のページへのリンクで説明を省略しているところもありますので、分かりにくい部分もあるかもしれません。

分からないところは出来る限りフォローしますので、気軽にコメントや Twitter で質問していただければと思います。

コメントを残す

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