試験運用中なLinux備忘録・旧記事

はてなダイアリーで公開していた2007年5月-2015年3月の記事を保存しています。

GtkBuilderとGladeについてと、PyGTK上での使用について(概要)

C言語のlibgladeやPyGTKのgtk.glade.XMLは、ユーザインターフェース情報を外部のXMLファイルから読み込んで使用する機能を提供する。
一方で、バージョン2.12以上のGTK+でも、同様の機能が標準で組み込まれている。これはGtkBuilderと呼ばれる。
C言語版(GTK+ 2.12以上)
http://library.gnome.org/devel/gtk/stable/GtkBuilder.html
PyGTK(PyGTK 2.12以上)
http://www.pygtk.org/docs/pygtk/class-gtkbuilder.html

uiファイルについてと、その作成方法

gladeファイルとは形式も使い方も異なる。拡張子は「.ui」。
上のC言語版のページにある「GtkBuilder UI Definitions」に書式が書かれているものの、手動で書くのは大変。そこでGTK+に含まれるgtk-builder-convertというツール(Pythonスクリプト)でgladeファイルから変換するという方法がとられる。
2008/6/11現在、GUIで.uiファイルを直接扱える(読み込み/編集/保存ができる)ツールはない。Gladeの3.4系ではまだ.uiファイルの読み書きはサポートされておらず(3.4.4ではダメ)、将来のバージョンで扱えるようになるまでは変換する他ない。変換したら編集できないという意味では多少扱いづらいが、サポートされるまでの辛抱。
(2009/3/29)バージョン3.5系のGladeでは.ui形式での読み書きがサポートされている。
GTK+付属のデモ(gtk-demo)を見ると、ツリービュー(リストやツリー構造を表示するGUI部品)の中のコラムや中のデータまで記述できるようだが、GUIでこのようなところまで編集できるのはまだ先になりそう。

このツリービューに対応付けられたリストデータ(GtkListStore)はuiファイル(/usr/share/gtk-2.0/demo/demo.ui)に書かれている

gtk-builder-convertのバグ?

GTK+ 2.12.9のgtk-builder-convert(gtk+-2.12.9/gtk/gtk-builder-convert)で変換を試したところ、エラーになってしまい、ダメだった(Pythonのバージョンは2.4.4を使用)。

$ gtk-builder-convert [入力ファイル].glade [出力ファイル].ui
Traceback (most recent call last):
  File "/usr/bin/gtk-builder-convert", line 745, in ?
    sys.exit(main(sys.argv))
  File "/usr/bin/gtk-builder-convert", line 733, in main
    conv.parse_file(input_filename)
  File "/usr/bin/gtk-builder-convert", line 161, in parse_file
    self._parse()
  File "/usr/bin/gtk-builder-convert", line 259, in _parse
    self._convert(node.getAttribute("class"), node)
  File "/usr/bin/gtk-builder-convert", line 284, in _convert
    self._convert_menu(node)
  File "/usr/bin/gtk-builder-convert", line 342, in _convert_menu
    item = self._convert_menuitem(uimgr, obj_node)
  File "/usr/bin/gtk-builder-convert", line 378, in _convert_menuitem
    item = self._convert_menuitem(uimgr, obj_node)
  File "/usr/bin/gtk-builder-convert", line 374, in _convert_menuitem
    self._add_action_from_menuitem(uimgr, obj_node)
  File "/usr/bin/gtk-builder-convert", line 425, in _add_action_from_menuitem
    properties['stock_id'] = child
UnboundLocalError: local variable 'child' referenced before assignment

バージョン2.12.10では修正されていて、動作した(「PyGTK + Gladeの簡単な例」のgladeファイルを使用)。

$ gtk-builder-convert pygtkgladetest.glade pygtkbuildertest.ui
Unhandled signal GtkImageMenuItem::select
Unhandled signal GtkImageMenuItem::deselect
Wrote pygtkbuildertest.ui

差分はこれだけ。

--- gtk+-2.12.9/gtk/gtk-builder-convert
+++ gtk+-2.12.10/gtk/gtk-builder-convert
@@ -422,7 +422,7 @@
 
         if get_property(node, 'use_stock') == 'True':
             if 'label' in properties:
-                properties['stock_id'] = child
+                properties['stock_id'] = properties['label']
                 del properties['label']
 
         properties['name'] = object_id

gladeファイルと機能が互換とは言えない?

上の変換時のメッセージを見て分かるように、メニュー項目の選択/選択解除に関するシグナル(select/deselect)は使えないようだ。変換ツールのソースを見たところ、メニュー項目で使えるシグナルは「activate」と「toggled」だけらしい。
この他、シンプルな例をPyGTKでgtk.Builder向けに修正したもので実験したところ、gtk.glade.XMLとは扱いが異なる部分も出てきていて、簡単に移行できるというわけでもないようだ(実際のコードは別記事で扱う)。

関連記事:

使用したバージョン:

  • GTK+ 2.12.9(2.12.9-r2)
  • Python 2.4.4(2.4.4-r13)
  • PyGTK 2.12.0
  • Glade 3.4.4