2007년 12월 11일 화요일

GtkBuilder 탐험

GTK+ 2.12에 포함된 GtkBuilder 기능에 대해 탐험해 보면,

GtkBuilderlibglade의 대체품이라고 말할 수 있다. GUI의 구성을 코드 내에서 하지 않고 XML 파일로 기술하고 런타임에 그 XML을 읽어들여서 UI를 구성한다. libglade를 써 봤다면 별로 새로운 건 아니겠지만, 일단 GTK+에 포함되어 버렸으니까 추가로 libglade를 링크할 필요가 없다는 장점이 있다. 또 일부 glade가 커버하지 못하고 있는 TreeView 따위의 복잡한 위젯도 쓸 수 있다. 요즘에 하드코딩으로 GTK+ 코딩하는 사람들이 거의 없다는 걸 생각해 보면 충분히 GTK+에 포함될 만한 기능이다. (GTK+가 너무 커진다 싶으면 언젠가 메이저 버전 뒤엎겠지.)

간단히 맛보기 필요한 소프트웨어: GTK+ 2.12 이상, pygtk (컴파일이 귀찮으므로)

import gtk
builder = gtk.Builder()
xml = '''
<interface>
  <object class="GtkWindow" id="cwwindow">
    <child>
      <object class="GtkButton" id="cwbutton">
        <property name="label">Build Me</property>
      </object>
    </child>
  </object>
</interface>
'''
builder.add_from_string(xml, len(xml))
win = builder.get_object('cwwindow')
win.show_all()
gtk.main()

위 파이썬 코드를 실행하면 이런 창이 나온다.
build me screenshot

libglade를 사용해 봤다면 XML 문법만 다르지 별 다른 점을 느끼지 못할 것이다. 또 대부분의 glade 파일은 gtk 2.12에 포함되어 있는 gtk-builder-convert 프로그램을 이용해 GtkBuilder용 XML 파일로 변환할 수 있다. ui.glade라는 파일로 저장을 했다고 하면,


$ /usr/bin/gtk-builder-convert ui.glade ui.xml
$ python
Python 2.4.4 (#2, Aug 16 2007, 02:03:40)
[GCC 4.1.3 20070812 (prerelease) (Debian 4.1.2-15)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import gtk
>>> builder = gtk.Builder()
>>> builder.add_from_file('ui.xml')
>>> builder.get_object('window1').show_all()
>>> gtk.main()

GtkBuilder의 장점은 "눈에 보이지 않는 오브젝트"를 정의할 떄 나온다. 특히 libglade를 사용할 때는 UI 디자인에서 지정하지 못하고 코딩으로 해결해야 했던 복잡한 위젯, 특히 모델/뷰/컨트롤러 개념이 필요한 TreeView, ComboBox 따위의 "모델"을 XML 파일에 집어 넣을 수 있다. 이 부분때문에 디자인과 프로그램이 완전히 분리하지 못했던 많은 코드를 분리할 수 있다.


<interface>
  <object class="GtkListStore" id="treemodel">
    <columns>
      <column type="gchararray"/>
      <column type="gint"/>
    </columns>
    <data>
      <row>
        <col id="0">cwryu</col>
        <col id="1">2</col>
      </row>
      <row>
        <col id="0">crew</col>
        <col id="1">1</col>
      </row>
      <row>
        <col id="0">clue</col>
        <col id="1">3</col>
      </row>
      <row>
        <col id="0">None of the Above</col>
        <col id="1">4</col>
      </row>
    </data>
  </object>
  <object class="GtkWindow" id="window1">
    <child>
      <object class="GtkTreeView" id="cwbutton">
        <property name="model">treemodel</property>
        <child>
          <object class="GtkTreeViewColumn" id="column0">
            <property name="title">Name</property>
            <child>
              <object class="GtkCellRendererText" id="r0"/>
          <attributes>
        <attribute name="text">0</attribute>
          </attributes>
        </child>
      </object>
    </child>
    <child>
          <object class="GtkTreeViewColumn" id="column1">
            <property name="title">Number</property>
            <child>
              <object class="GtkCellRendererText" id="r1"/>
          <attributes>
        <attribute name="text">1</attribute>
          </attributes>
        </child>
      </object>
        </child>
      </object>
    </child>
  </object>
</interface>


위의 XML 파일을 마찬가지의 python 코드로 돌리면,
사용자 삽입 이미지

이렇게 스트링-숫자 형식의 "모델"과 cwryu/crew/... 따위의 데이터를 포함할 수 있다.

현재 그놈 프로그램은 거의 glade만을 사용하고 있다. 내년 3월이나 9월 릴리스에서 libglade에서 옮겨올 수 있을까? 많은 사람들이 어려움을 호소하는 걸 보면, 얼핏 보면 깔끔하고 좋아 보이지만 실제 적용하기는 쉽지 않은 모양이다.

댓글 1개:

  1. 쩝. d-feet라는 것이 gtk.Builder를 사용하게 되어 있는데,

    제가 쓰고 있는 건 gtk 2.10.2라서 못 쓰네요.

    그래서 거꾸로 gtk.Builder의 xml file를 보면서 glade로 옮기는 중...

    답글삭제

뜬금없이 문법 따위를 지적하거나, 오래된 글에 링크가 깨진 걸 지적하는 등의 의미 없는 댓글은 자제해 주시기 바랍니다. 그러한 경우 답 없이 삭제합니다. 또한 이해 당사자이신 경우 숨어서 옹호하지 마시고 당사자임을 밝히시길 바랍니다.

참고: 블로그의 회원만 댓글을 작성할 수 있습니다.