GTK.Builder
表示
GTK.Builderの基本
[編集]GTK.Builderは、UIをコードから分離してXMLで定義するためのGTKの機能です。UIの構造をXMLで記述し、プログラムから動的に構築できます。
基本的な使用方法
[編集]import gi gi.require_version('Gtk', '3.0') from gi.repository import Gtk builder = Gtk.Builder() builder.add_from_string(""" <?xml version="1.0" encoding="UTF-8"?> <interface> <object class="GtkWindow" id="window"> <property name="title">Builder Example</property> <child> <object class="GtkBox"> <property name="orientation">vertical</property> <child> <object class="GtkButton" id="button1"> <property name="label">Click Me</property> </object> </child> </object> </child> </object> </interface> """) window = builder.get_object("window") window.connect("destroy", Gtk.main_quit) window.show_all() Gtk.main()
UIの定義
[編集]複雑なレイアウト例
[編集]ui_string = """ <?xml version="1.0" encoding="UTF-8"?> <interface> <object class="GtkWindow" id="main_window"> <property name="default-width">400</property> <property name="default-height">300</property> <child> <object class="GtkGrid" id="grid"> <property name="row-spacing">6</property> <property name="column-spacing">6</property> <child> <object class="GtkLabel"> <property name="label">Name:</property> <layout> <property name="left-attach">0</property> <property name="top-attach">0</property> </layout> </object> </child> <child> <object class="GtkEntry" id="name_entry"> <layout> <property name="left-attach">1</property> <property name="top-attach">0</property> </layout> </object> </child> <child> <object class="GtkButton" id="submit_button"> <property name="label">Submit</property> <layout> <property name="left-attach">1</property> <property name="top-attach">1</property> </layout> </object> </child> </object> </child> </object> </interface> """
シグナルの接続
[編集]シグナルハンドラーの実装
[編集]class Handler: def __init__(self, builder): self.builder = builder def on_submit_button_clicked(self, button): entry = self.builder.get_object("name_entry") text = entry.get_text() print(f"Submitted: {text}") def on_window_destroy(self, *args): Gtk.main_quit() builder = Gtk.Builder() builder.add_from_string(ui_string) handler = Handler(builder) # シグナルの接続 window = builder.get_object("main_window") button = builder.get_object("submit_button") window.connect("destroy", handler.on_window_destroy) button.connect("clicked", handler.on_submit_button_clicked)
カスタムウィジェット
[編集]カスタムウィジェットの定義と使用
[編集]class CustomWidget(Gtk.Box): def __init__(self): super().__init__() builder = Gtk.Builder() builder.add_from_string(""" <interface> <object class="GtkBox" id="custom_box"> <property name="orientation">horizontal</property> <child> <object class="GtkLabel" id="label"> <property name="label">Custom Widget</property> </object> </child> <child> <object class="GtkButton" id="button"> <property name="label">Click</property> </object> </child> </object> </interface> """) box = builder.get_object("custom_box") button = builder.get_object("button") button.connect("clicked", self.on_button_clicked) self.pack_start(box, True, True, 0) def on_button_clicked(self, button): print("Custom widget button clicked!")
動的UIの構築
[編集]実行時のUI変更
[編集]class DynamicUI: def __init__(self): self.builder = Gtk.Builder() self.builder.add_from_string(""" <interface> <object class="GtkWindow" id="window"> <child> <object class="GtkBox" id="main_box"> <property name="orientation">vertical</property> </object> </child> </object> </interface> """) self.main_box = self.builder.get_object("main_box") def add_new_button(self): new_button = Gtk.Button(label="Dynamic Button") new_button.connect("clicked", self.on_dynamic_clicked) self.main_box.pack_start(new_button, True, True, 0) new_button.show() def on_dynamic_clicked(self, button): print("Dynamic button clicked!")
リソース管理
[編集]リソースファイルの使用
[編集]- resources.xml
<!-- resources.xml --> <?xml version="1.0" encoding="UTF-8"?> <gresources> <gresource prefix="/org/example/app"> <file>ui/interface.ui</file> <file>css/style.css</file> </gresource> </gresources>
from gi.repository import Gio resource = Gio.Resource.load('resources.gresource') Gio.Resource._register(resource) builder = Gtk.Builder() builder.add_from_resource('/org/example/app/ui/interface.ui')
エラー処理とデバッグ
[編集]try: builder = Gtk.Builder() builder.add_from_string(ui_string) except GLib.Error as e: print(f"Builder error: {e.message}") sys.exit(1) # オブジェクトの存在確認 button = builder.get_object("submit_button") if button is None: print("Error: Button not found in UI definition") sys.exit(1)
Glade との比較
[編集]GTK.Builder
[編集]- メリット
-
- プログラムによる完全な制御が可能
- 動的なUI生成が容易
- コードでのデバッグが可能
- バージョン管理が容易
- デメリット
-
- UIの視覚的な設計が困難
- XMLの手動編集が必要
- レイアウトの試行錯誤が時間がかかる
Glade
[編集]- メリット
-
- 視覚的なUI設計が可能
- WYSIWYG編集
- レイアウトの即時プレビュー
- プロパティの視覚的な編集
- デメリット
-
- 外部ツールへの依存
- 動的なUI生成が比較的複雑
- カスタムウィジェットの扱いが面倒
使い分けの指針
[編集]- GTK.Builderを選ぶ場合:
- プログラムによるUI生成が必要
- 動的なUIが多い
- 外部依存を減らしたい
- コードベースでの完全な制御が必要
- Gladeを選ぶ場合:
- 静的なUIが中心
- デザイナーとの協業
- 迅速なプロトタイピング
- 視覚的なUI設計を重視
多くの場合、両方を組み合わせて使用することで最適な開発フローを実現できます。