bravo's blog

多分ググっても出てこないようなプログラミング記事を目指します!

(OSX) PyQtでDockアイコンへのドロップを実装する その2

OSX用に仕上げる

その1で作ったプログラムを、より実用的なアプリケーションらしく使えるようにするには、 OSXの仕様に合わせる必要があります。仕様にあわせたファイル郡のことをBundle(バンドル)といいます。 身近なものでは、アプリケーションフォルダの中にあるものです。 Bundleはターミナルから見ればディレクトリになっています。

py2appを使う

OSX用のファイルを作るために、py2appというツールを追加インストールします。 (ここではpipコマンドでインストールしています。)

% pip install py2app
(出力は省略)

py2app用のファイルを作る

まずはpy2app用のファイルを作ります。PyQtのプログラムは「DropToMe.py」という名称で保存していると仮定します。 DropToMe.pyがあるディレクトリで以下のコマンドを実行します。

% py2applet --make-setup DropToMe.py
Wrote setup.py

するとsetup.pyというファイルが生成されます。中身は以下のようになっています。

"""
This is a setup.py script generated by py2applet

Usage:
    python setup.py py2app
"""

from setuptools import setup

APP = ['DropToMe.py']
DATA_FILES = []
OPTIONS = {'argv_emulation': True}

setup(
    app=APP,
    data_files=DATA_FILES,
    options={'py2app': OPTIONS},
    setup_requires=['py2app'],
)

setup.pyの編集

PyQtライブラリを明示的にインポートする設定と、 Webブラウザのリンクのドロップへの対応ができるように、 以下のように編集します。

"""
This is a setup.py script generated by py2applet

Usage:
    python setup.py py2app
"""

from setuptools import setup

APP = ['DropToMe.py']
DATA_FILES = []

urltypes = [{'CFBundleURLName': 'com.example.DropToMe',
             'CFBundleURLSchemes': ['http', 'https']}
            ]
plist = dict(
    CFBundleURLTypes = urltypes
    )

OPTIONS = {'argv_emulation': True,
           'includes':['sip', 'PyQt5.QtCore', 'PyQt5.QtGui', 'PyQt5.QtWidgets'],
           'plist': plist,
           }

setup(
    app=APP,
    data_files=DATA_FILES,
    options={'py2app': OPTIONS},
    setup_requires=['py2app'],
)

diffコマンドの表示は以下のようになっています。OPTIONSの内容が変化していることがわかります。

 APP = ['DropToMe.py']
 DATA_FILES = []
-OPTIONS = {'argv_emulation': True}
+urltypes = [{'CFBundleURLName': 'com.example.DropToMe',
+             'CFBundleURLSchemes': ['http', 'https']}
+            ]
+plist = dict(
+    CFBundleURLTypes = urltypes
+    )
+OPTIONS = {'argv_emulation': True,
+           'includes':['sip', 'PyQt5.QtCore', 'PyQt5.QtGui', 'PyQt5.QtWidgets'],
+           'plist': plist,
+           }

 setup(
     app=APP,

Bundleを生成しましょう

いよいよBundleの生成です。とは言うものの、コマンド1つで終わりです。

% python setup.py py2app -A
(出力省略)
*** creating application bundle: DropToMe ***
Done!

無事にコマンドの実行が完了すると、distディレクトリの中に「DropToMe.app」というディレクトリが見えます。 これがBundleになります。また「-A」オプションで生成したBundleは今動いているシステムローカルでのみ動作します。 今の状態から配布できるBundleにするにはdist、buildディレクトリを削除してから「-A」オプションを入れずに実行します。

実行してみましょう


(OSX) PyQtでDockアイコンへのドロップを実装する その2

補足

setup.pyの中のOPTIONSで指定しているCFBundleURLNameの内容は 一意性のために「com.example.DropToMe」のように逆順のドメイン名表記が使用されます。

PR