Zlaunch開発経緯 / Claudeによる3日間の汗と涙の苦闘記録

Zlaunch フェーズ①開発経緯要約

目次

Ver 1.0 〜 Ver 1.2.3まで

概要

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

名作Claunch 作者のHPより

テキトーだが設計書を書いてみた結果

Claudeにはこれまで何度かプライベート用途のアプリを作成依頼してきたが、いつも思いつきメモ片手で依頼しては修正を重ねていた。
今回は多機能でそれなりにレベルの高い作品になるはずなので今回は事前に仕様書を(ChatGPTのアドバイスを受けながら)きっちりと作り上げてからClaudeに依頼した。おかげでマークダウンテキストの書き方も覚えた。(^。^)
最初のもたつきを解消したあとは開発スピードが圧倒的に爆速になった要因のはず。
それとともに、自分がイメージしていたデザインと操作性も最初から完成品レベルで出来上がったことも同じ理由。


以下、Claudeによる自己要約記録である。スクショ挿入以外は原文のまま。
注意書きで、AI の判断によって独自のコーディングをしないよう仕様準拠としていた。
このことが、後の深刻な混乱を招く元凶になるとは夢にも思わなかった。(´д`)
相手が人間でもAI でも、十分なスキルのない者が条件をつけると良い結果を生まないという教訓になった。

フェーズ① : Tkinter で開発開始(〜Ver 0.1)

構成

  • Zlaunch.py / config_manager.py / register_dialog.py
  • settings_dialog.py / single_instance.py
  • 設定ファイル: ~/appli/ZLoanch/data/config.json

実装内容

  • 5タブ(常用/画像/音楽/ユーティリティ/その他)
  • 7列×4行の機能ボタングリッド
  • ボタン登録ダイアログ(コマンド/フォルダ/ファイル/システム機能)
  • JSON設定の保存・読込
  • 単一インスタンス制御(Unixドメインソケット /tmp/zlaunch.sock

苦戦した点:ボタンのpxサイズ固定問題

Tkinterの Buttonwidth/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

開発を振り返って

「Claudeでさえ半日費やしても出来なかったのが、コロンブスの卵でやり直し提案したら3秒で基本画面が完成した。キーワードは自分の開発ツール指定のミスだった。」
— ひこさま

Tkinterという最初の選択が遠回りの原因だったが、
PySide6への切り替えという判断がプロジェクト全体を救った。
AIとの協業においても、方向性の判断は人間側が行うことの重要性を示す好例。

機能の修正に関する会話が延々と続き、非常に長いチャットになったのでメモをまとめる気もせず、AI の得意技である要約を遠慮なく依頼したのだった。
初心者の方は専門用語が多くて読みにくいとは思うが、自分のための記録だから。これでいいのだ。(^。^)

よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!

コメント

コメントする

CAPTCHA


目次