開発のきっかけと2列レイアウトへの挑戦
前回の記事でmacOS向けのAIチャット自動送信ツール「ChatSpooler」の基本機能を完成させました。しかし、実際に使ってみると改善点が見えてきました。
特にUIの配置が作業効率を妨げていて、従来のレイアウトでは送信キューや送信履歴の高さが狭くて一覧できません。
そこで、画面上部を左右2列に分割する新しいレイアウトを検討しました。左列に送信先設定、右列に文章入力を配置することで、両方の操作を同時に見ながら行えるようになります。
レイアウト変更の設計と実装
新しいレイアウトの設計では、効率的な画面使用を最優先に考えました。上部を2列に分割し、送信キューと送信履歴を左右に並列配置することで、より多くの情報を同時に表示できます。
tkinter(Pythonの標準GUI ライブラリ)のgridレイアウトマネージャーを使用して、柔軟な画面配置を実現しました。gridは表のようにウィジェットを配置できる仕組みで、列と行の重み設定により画面サイズの変更に対応できます。
def create_top_area(self, parent):
"""上部2列エリアを作成"""
top_frame = ttk.Frame(parent)
top_frame.grid(row=0, column=0, columnspan=2, sticky=(tk.W, tk.E, tk.N, tk.S), pady=(0, 10))
self.create_left_column(top_frame)
self.create_right_column(top_frame)
top_frame.columnconfigure(0, weight=1)
top_frame.columnconfigure(1, weight=1)
top_frame.rowconfigure(0, weight=1)
Code language: PHP (php)
この設定により、左右の列が常に同じ幅を保ちながら画面サイズに追従します。
送信方法選択UIの改良
従来はラジオボタンを縦に並べて送信方法を選択していましたが、これが縦方向のスペースを圧迫していました。コンボボックス(ドロップダウンリスト)に変更することで、省スペース化を実現しました。
method_combo = ttk.Combobox(method_frame, textvariable=self.method_var,
values=["applescript", "clipboard", "pyautogui"],
state="readonly", width=15)
Code language: PHP (php)
この変更により、機能性を保ちながら画面の有効活用ができるようになりました。
大規模コードのモジュール分割(ui.py)
開発が進むにつれ、ui.pyファイルが500行を超える大きなファイルになりました。コードが長くなると、機能追加時の影響範囲がわかりにくくなり、デバッグも困難になります。
そこで、責任別に3つのファイルに分割しました。
分割後のファイル構成
# ui_main.py - メインクラスと設定管理
class AutoChatSenderUI(UIComponents, UIHandlers):
def __init__(self, root: tk.Tk):
self.root = root
self.setup_ui()
self.setup_callbacks()
# ui_components.py - UI部品の作成
class UIComponents:
def create_app_selection_area(self, parent):
"""アプリケーション選択エリアを作成"""
app_frame = ttk.LabelFrame(parent, text="送信先設定")
# UI要素の配置処理
# ui_handlers.py - イベント処理
class UIHandlers:
def add_to_queue(self):
"""テキストをキューに追加"""
text = self.text_area.get("1.0", tk.END).strip()
if self.core_manager.queue_manager.add_item(text, wait_time):
self.check_auto_send()
この分割により、新機能を追加する際に適切なファイルを選択でき、コードの保守性が大幅に向上しました。例えば、新しいボタンを追加したい場合はui_components.py、そのボタンの動作を定義したい場合はui_handlers.pyを編集すれば済みます。
送信制御機能の大幅強化(_sending_loop)
実際の使用場面を想定すると、送信タイミングの細かい制御が必要になることがわかりました。特に、送信開始の遅延時間を調整したい場面や、全送信完了後も待機を継続したい場面が想定されます。