今回は、簡単なMacのスタンドアローンアプリを実装して、動作させてみるメモです。
具体的には、PythonのGUIライブラリ
その後、py2appを利用してMac用にApp形式にビルドして実行してみます。
尚、dmgファイルを作成する内容は含まれません。
Windows用にexe形式にビルドすることも含まれません。
(しかし、メモの内容で実装してpy2exeを利用すれば、exeファイルを生成できると思います)
環境
- macOS:Sonoma 14.6
- PyCharm 2024.1.4 (Professional Edition)
- Python:3.11
- Tkinter:8.6
- py2app:0.28.8
GUIアプリ実装
- 初期表示で、テキストエリア、リセットボタン、メニュー(フォルダ選択、解析結果保存、終了)を配置
- フォルダを選択した場合そのフォルダ内容を解析して、
存在するフォルダとファイルをテキストエリア部分に一覧表示する- サイズ(MB)表示有り
- 末尾にトータルファイル数表示、トータルサイズ(MB)表示
- Save Structureで、現状のテキストエリアの内容を保存
実装コード
import tkinter as tk
from tkinter import filedialog
import os
import threading
class FolderAnalyzeApp:
def __init__(self, root):
self.root = root
self.root.title("Folder Structure Viewer")
# メインフレームを作成
main_frame = tk.Frame(self.root)
main_frame.pack(expand='yes', fill='both')
# テキストエリアを作成し、メインフレームに配置
self.text_area = tk.Text(main_frame, wrap='word')
self.text_area.pack(expand='yes', fill='both', side='top')
# リセットボタンを作成し、メインフレームに配置
reset_button = tk.Button(main_frame, text="Reset", command=self.reset_text_area)
reset_button.pack(side='bottom')
# メニューバーを作成
menu_bar = tk.Menu(self.root)
file_menu = tk.Menu(menu_bar, tearoff=0)
file_menu.add_command(label="Select Folder", command=self.select_folder)
file_menu.add_command(label="Save Structure", command=self.save_structure)
file_menu.add_separator()
file_menu.add_command(label="Exit", command=self.exit_app)
menu_bar.add_cascade(label="File", menu=file_menu)
# メニューバーをウィンドウに設定
self.root.config(menu=menu_bar)
def select_folder(self):
# フォルダ選択ダイアログを表示
folder_path = filedialog.askdirectory()
if folder_path:
# 別スレッドでフォルダ構造を取得
threading.Thread(target=self.process_folder, args=(folder_path,)).start()
def process_folder(self, folder_path):
# 処理中メッセージを表示
self.text_area.delete(1.0, tk.END)
self.text_area.insert(tk.END, "Processing...\n")
self.root.update_idletasks()
# フォルダ構造を取得し、テキストエリアに挿入
folder_structure, total_files, total_size = self.get_folder_structure(folder_path)
self.text_area.delete(1.0, tk.END)
self.text_area.insert(tk.END, folder_structure)
# 総ファイル数と総サイズをテキストエリアの最後に挿入
self.text_area.insert(tk.END, f"\nTotal files: {total_files}\n")
self.text_area.insert(tk.END, f"Total size: {total_size:.2f} MB\n")
def get_folder_structure(self, folder_path):
structure = ""
total_files = 0
total_size = 0.0
# フォルダを走査
for root, dirs, files in os.walk(folder_path):
level = root.replace(folder_path, '').count(os.sep)
indent = ' ' * 4 * level
folder_size = sum(os.path.getsize(os.path.join(root, f)) for f in files) / (1024 * 1024)
structure += f"{indent}{os.path.basename(root)}/ ({folder_size:.2f} MB)\n"
sub_indent = ' ' * 4 * (level + 1)
for f in files:
# ファイルサイズを取得し、MBに変換
file_size = os.path.getsize(os.path.join(root, f)) / (1024 * 1024)
structure += f"{sub_indent}{f} ({file_size:.2f} MB)\n"
total_files += 1
total_size += file_size
return structure, total_files, total_size
def save_structure(self):
# ファイル保存ダイアログを表示
file_path = filedialog.asksaveasfilename(defaultextension=".txt",
filetypes=[("Text Files", "*.txt"), ("All Files", "*.*")])
if file_path:
# テキストエリアの内容をファイルに書き込む
with open(file_path, 'w') as file:
file.write(self.text_area.get(1.0, tk.END))
def reset_text_area(self):
# テキストエリアをクリア
self.text_area.delete(1.0, tk.END)
def exit_app(self):
# アプリケーションを終了
self.root.quit()
if __name__ == "__main__":
root = tk.Tk()
app = FolderAnalyzeApp(root)
root.mainloop()
py2app Appビルド
作成したPythonプログラムをApp形式にビルドしてみます。
今回は、py2appを利用します。
py2appインストール
pip3 install -U py2app
後述するsetup.pyを先に用意した場合、以下コマンドよりインストールすることもできます。
python setup.py install
setup.py 作成
py2appでアプリをビルドするには、
setup.pyという設定ファイルが必要になります。
以下のコマンドでsetup.pyを自動生成することができます。
py2applet --make-setup FolderAnalyzeApp.py(GUIアプリのPythonファイルを指定)
自動生成したままでも利用できますが、
簡単なアイコンなどを設定してみたいと思います。
"""
This is a setup.py script generated by py2applet
Usage:
python setup.py py2app
"""
from setuptools import setup
APP = ['FolderAnalyzeApp.py']
DATA_FILES = []
OPTIONS = {
'iconfile': 'logo.icns', # アイコンファイルのパスを指定
'plist': {
'CFBundleName': 'FolderAnalyzeApp', # アプリケーション名
'CFBundleDisplayName': 'Folder Analyze App', # 表示名
'CFBundleVersion': '0.1.0', # バージョン
'CFBundleIdentifier': 'com.test.FolderAnalyzeApp', # バンドル識別子
},
}
setup(
app=APP,
data_files=DATA_FILES,
options={'py2app': OPTIONS},
setup_requires=['py2app'],
)
ビルド実行
以下コマンドでビルドを行います。
python setup.py py2app
Done!の文字が表示されて、エラーが無ければ、distというフォルダが生成されます。
もしもエラーになった場合や、再度ビルドしたい場合には、
こちらのdistフォルダごと削除して再実行を行います。
IDEによって見え方は異なりますが、
Finder等で表示すると、アプリケーションとして認識されます。
Finder等でアプリ名.appファイルをダブルクリックするだけで起動することができます。
今回のメモは以上となります。
Tkinterとpy2appを利用すれば、
Pythonでも簡単にMacアプリを作成できます。
ただし、少し試した感じですと、
入力系などのところでシビアな性能を求められるアプリの場合、
Tkinterだけですと調整が困難になる気がします。
しかし、ちょっとした自作ツールを作成するには十分だと思います。
今度、dmgファイルとして配布する場合の対応もメモしてみたいと思います。