Pythonでファイルをdrag and dropで渡すアプリを作ろうと思った時、 TkinterとNuiktaを使って作ろうとしたら M1 MacなどのARM Mac用を作るのがちょっと面倒だった話。
PythonでのGUIアプリ開発
tkinter はGUIツールに対するPythonの標準インターフェースです。
PythonでGUIアプリを作るには flet などのフレームワークを使うこともできますが、 今回はdrag and dropでファイルを渡すアプリを作ろうと思って、 fletでは現状サポートされておらず、 tkinterであればそれようのライブラリが既に存在するのでtkinterを使うことにしました。
tkinterはPythonのインストール状況によってはインストールされておらず、
1 2 3 4 |
|
のようにエラーが出ることがありますが、その場合は別途インストールする必要があります。
MacやLinuxでHomebrewでPythonをインストールしている場合は、
1
|
|
などインストールしているのと同じバージョンのtkinterをインストールします。
Linuxでaptを使ってPythonをインストールしている場合は、
1
|
|
WindowsならWelcome to Python.orgからインストーラをダウンロードしてインストールするとデフォルトでtkinterもインストールされます。
tkinterdnd2
tkinterdnd2 はtkinterの拡張ライブラリで、 drag and dropをサポートしています。
1
|
|
でインストールして
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
|
みたいなスクリプトを実行するとウィンドウが出てきてそこにファイルを ドロップするとファイル名が表示されるようなアプリができます。
tkinterdnd2-universal
tkinterdnd2はx86_64のMacやWindowsなどで動作しますが、 ARM Macでは動作しません。
そこで、ARM Macでも動作するようにしたのが tkinterdnd2-universal
tkinterdnd2
の代わりに
tkinterdnd2-universal
をpip install
すると
上の同じスクリプトでARM Macでも動作するようになります。
ただ、PyPIにはまだ残っているのでpip
でのインストールは可能で
ソースコードも直接ダウンロードしたり出来ますが、
GitHubで作者がアカウント自体を削除したのかレポジトリが残ってません。
https://github.com/blacklein/tkinterdnd2-universal
最終リリースは1.7.3で2023/3/21。
tkinterdnd2の方もPyPIにリリースされてるものはそもそもforkされたもので 0.3.0が2021/6/6にリリースされたのが最後です。
他にも似たようなものはいくつかあって、より良いものもあるかもしれませんが、 とりあえず今回は見た感じ一番メジャーなこれを使いました。
Nuitka
Nuitka はWindows用のexeやMac用のappを作るツールです。
同様に実行ファイルを作るツールとしては PyInstaller などがありますが、ほとんどのものはPythonを含めて実行ファイルを作って一時ディレクトリにPythonコードを展開して実行するので 実行ファイルのサイズが大きくなるのと実行時間が遅い、 簡単にソースコードが見えてしまうという問題があります。
NuitkaはPythonのコードをC言語に変換してコンパイルするので 実行ファイルのサイズが比較的小さく、実行時間も速く、 ソースコードも見えないようになります。
今回も最初PyInstallerを使ってうまくいきましたが、 Nuiktaで作れればそちらの方が良いかと思い試してみました。
Nuitkaはpip
でインストールできます。
1
|
|
あとはWindowsであれば
1
|
|
のようにしてdrag_and_drop.exe
ファイルを作ることが出来ます。
Macなら
1
|
|
でdrag_and_drop..app
ファイルを作ることが出来ます。
ARM Macでの実行
が、ARM Macで上記コマンドを実行すると
1
|
|
といったエラーが出ます。
上にも書いた通り、tkinterdnd2の方をインストールするとここではエラーは出ずアプリは作れますが実行時に
1
|
|
といったarm用のライブラリではないとエラーが出ます。
tkinterdnd2-universalを使うとスクリプトは実行できますが、
コンパイル時に上のFileNotFoundError
が出ます。
実際にsite-packagesの中を見てみると
tkinterdnd2の方にはosx64
とwin64
とlinux64
がありますが、
tkinterdnd2/tkinterdnd2/tkdnd at master · Eliav2/tkinterdnd2
tkinterdnd2-universalの方にはosx-arm64, osx-osx64, linux-arm64, linux-x64, win-arm64, win-x64があります(PyPIにあるコード参照)。
これに関して、NuitkaではライブラリがPythonコード以外のライブラリなどを含む場合、 あらかじめ調べておいてコンパイルするようになっているようです。
Compile seems to not include tkdnd package needed for tkinterdnd2 · Issue #1562 · Nuitka/Nuitka
tkinterdnd2も以前は上記のライブラリが入らず実行ファイルを作っても実行できませんでしたが、 上のIssueで対応されたようです。
が、これはtkinterdnd2の方で対応されたもので、 同じ名前でいれるtkinterdnd2-universalの方でライブラリのディレクトリ名が違うとうまくインストールできません。
tkinterdnd2/tkinterdnd2/TkinterDnD.py
の中でも、こちらのtkinterdnd2の方はosx64
とwin64
とlinux64
というディレクトリ名から選ぶようになっていますが、
tkinterdnd2-universalの方はアーキテクチャも考慮してosx-arm64
, osx-osx64
, linux-arm64
, linux-x64
, win-arm64
, win-x64
というディレクトリ名から選ぶようになっています。
実際にNuitkaが行うのは必要なライブらいフォルダを実行ファイルの中にコピーすることなので、 ARM Macで行う場合、tkinterdnd2-universalをインストール後、 site-packagesの中にある
- tkinterdnd2/TkinterDnD.pyのコードの中の
osx-osx64
をosx64
に変更 - tkinterdnd2/tkdndの中の
osx-osx64
ディレクトリをosx64
に変更
してやればOK。
1 2 3 4 5 |
|
これで
1
|
|
でARM Mac用のアプリが作れます。
Intel Macで作る場合は tkinterdnd2の方をインストールしてNuitkaでコンパイルするだけでOKです。