Zlaunch フェーズ①開発経緯要約
Ver 1.0 〜 Ver 1.2.3まで
概要
今回はWindowsのランチャーアプリCLaunchをZorinOS(Linux)で再現することを目指し、
PythonとGUIライブラリを使って「ZLoanch/ゼットローンチ」を開発した記録である。
(正確には”ゼットランチ”だがあえてこの名称にした) ※後に「Zlaunch」に改称
開発計画はClaude.aiとの協業で進めた。


テキトーだが設計書を書いてみた結果
Claudeにはこれまで何度かプライベート用途のアプリを作成依頼してきたが、いつも思いつきメモ片手で依頼しては修正を重ねていた。
今回は多機能でそれなりにレベルの高い作品になるはずなので今回は事前に仕様書を(ChatGPTのアドバイスを受けながら)きっちりと作り上げてからClaudeに依頼した。おかげでマークダウンテキストの書き方も覚えた。(^。^)
最初のもたつきを解消したあとは開発スピードが圧倒的に爆速になった要因のはず。
それとともに、自分がイメージしていたデザインと操作性も最初から完成品レベルで出来上がったことも同じ理由。
以下、Claudeによる自己要約記録である。スクショ挿入以外は原文のまま。
注意書きで、AI の判断によって独自のコーディングをしないよう仕様準拠としていた。
このことが、後の深刻な混乱を招く元凶になるとは夢にも思わなかった。(´д`)
相手が人間でもAI でも、十分なスキルのない者が条件をつけると良い結果を生まないという教訓になった。
フェーズ① : Tkinter で開発開始(〜Ver 0.1)
構成
Zlaunch.py/config_manager.py/register_dialog.pysettings_dialog.py/single_instance.py- 設定ファイル:
~/appli/ZLoanch/data/config.json
実装内容
- 5タブ(常用/画像/音楽/ユーティリティ/その他)
- 7列×4行の機能ボタングリッド
- ボタン登録ダイアログ(コマンド/フォルダ/ファイル/システム機能)
- JSON設定の保存・読込
- 単一インスタンス制御(Unixドメインソケット
/tmp/zlaunch.sock)
苦戦した点:ボタンのpxサイズ固定問題
Tkinterの Button は width/height が文字数基準であり、px指定ができない。
以下の手法を順番に試したが、いずれも問題が発生した。
| 試した手法 | 問題 |
|---|---|
| Frame + grid_propagate(False) | packで子Widgetのサイズが親に伝播して崩れる |
| Button + ダミー画像(1x1px) | refresh時にimage=””でpx基準が解除される |
| 文字数換算でwidth/height指定 | フォント環境依存でズレる |
最終的な解決策:place()レイアウトマネージャを使用。place()は唯一、子Widgetのサイズ要求が親に伝播しない。
実機テスト(test_grid_minimal.py)で実証済み。
教訓
- Tkinterは1991年設計の枯れたツールキットであり、現代的なレイアウト機構を持たない
- ボタンのドラッグ&ドロップ移動もTkinterでは実装困難
- 「ボタンを並べるだけ」で相当な時間を要した
コロンブスの卵:PySide6への切り替え(Ver 1.2.0)
切り替えの経緯
ひこさまの提案により、GUIライブラリをTkinterからPySide6に変更。
これが決定的な転換点となった。
Tkinterで半日格闘していた「ボタンの敷き詰め」が、
PySide6ではsetFixedSize(120, 90)の1行で一発解決。

PySide6を選んだ理由
QPushButton.setFixedSize(px, px)でpxを直接指定可能QDrag/QMimeDataでドラッグ&ドロップが標準機構で実装できる- スタイルシート(CSS)でデザインの自由度が高い
- LGPLライセンスで個人利用に問題なし
Ver 1.2.0 実装内容
- OSネイティブのタイトルバーを非表示(
FramelessWindowHint) - タイトルエリアのドラッグでウィンドウ移動
- ボタングリッド:
QFrame+QVBoxLayoutでアイコン上部・タイトル下部の縦レイアウト - アイコン画像の表示(
QPixmapで32pxに縮小) - ボタンタイトルの折り返し(
QLabel.setWordWrap(True)) - 同一タブ内でのドラッグ&ドロップ入れ替え
- 「ファイル」タブを「常用」の右隣に追加
- 既存config.jsonへの自動マイグレーション
- タブ並べ替え(設定画面でドラッグ)
- ESCキーでプロセス終了
結果
起動直後から「まんまCLaunchになった」という状態を実現。

Ver 1.2.1 〜 1.2.3 : 細部の改善
修正内容一覧
| 項目 | 内容 |
|---|---|
| ウィンドウドラッグ | QMainWindowのmouseイベントがFrameless環境で子Widgetに横取りされる問題をeventFilter方式で解決 |
| アイコン選択 | システムアイコンフォルダ /usr/share/icons/Zorin/48x48 をQFileDialogで直接開く |
| 登録ダイアログ | 項目順を「タイトル→コマンド」に変更、タイトルを2行入力に、Ctrl+Enterで改行 |
| アイコン入力ボックス | setReadOnly(False) で直接入力可能に(ひこさまがセルフ対応) |
| Menuキー動作 | Wayland環境の制限を確認・対応 |
Wayland環境でのMenuキー問題と解決

問題:ZorinOSはWayland環境のため、raise_()/activateWindow() で
他アプリのフォーカス中に自ウィンドウを最前面に持ってくることができない
(Waylandのセキュリティ仕様による制限)。
解決策:「2回押し運用」で対応。
- 隠れた状態でMenuキー1回目 → ZLaunchを終了
- Menuキー2回目 → ZLaunchを起動(最前面で)
デバッグ過程で確認できたこと:
- Unixドメインソケット通信は正常動作
QMetaObject.invokeMethodでスレッドをまたいだメソッド呼び出しが確実
技術スタック(最終)
| 項目 | 内容 |
|---|---|
| 言語 | Python 3.12 |
| GUIフレームワーク | PySide6 |
| データ永続化 | JSON(config.json) |
| 単一インスタンス制御 | Unixドメインソケット(/tmp/zlaunch.sock) |
| 動作環境 | ZorinOS(GNOME/Wayland) |
| バージョン管理 | APP_VERSION 定数(ZLoanch.py冒頭) |
Ver 2.0 への課題
- システムトレイ常駐(pystray等が必要)
- タブをまたぐドラッグ&ドロップ
- タブの追加・削除UI
- アプリアイコン自動登録ユーティリティ(GPTと協業で開発中)
- 設定のバックアップ・エクスポート/インポートUI
開発を振り返って
Tkinterという最初の選択が遠回りの原因だったが、
PySide6への切り替えという判断がプロジェクト全体を救った。
AIとの協業においても、方向性の判断は人間側が行うことの重要性を示す好例。








コメント