PyGObjectで使用するXMLデータの作成
PythonでGtk4を使用する場合は、PyGObjectによりXMLドキュメントであるテンプレート(GtkBuilder UI Definition XML Document)から、インターフェイスを作成することができます。Pythonでインターフェイスを作成するのに比べて、XMLドキュメントでユーザーインターフェイスを作成すると、Widget同士の配置が見やすくインターフェイスの変更が容易であるというメリットがあるので、利用した方が良いと思います。
今回は、PyGObjectで使用したGtk4のインターフェイスの作成をおこなえるように、PyGObjectで使用するXMLデータの書き方について紹介します。
XMLデータの書き方
XMLデータの書き方を紹介するために、今回は下の図のようなインターフェイスを作成するXMLデータを以下の4点に分けて説明します。
・ 1. XMLの指定
・ 2. ウィンドウの追加
・ 3. ウィンドウへの子Widget(Gtk.Box)の追加
・ 4. Gtk.Boxへの子Widgetの追加
1. XMLの指定
PyGObjectで使用するxmlデータは、最初にXMLでお決まりの<?xml …?>を書き、次に<interface></interface>を書いて、その中にWidgetをウィンドウから順番に記入します。
<?xml version="1.0" encoding="UTF-8"?>
<interface>
</interface>
2. ウィンドウの追加
class名:windowのGtk.Windowを定義するには、以下のように書きます。class名は、pythonプログラムでxmlファイルを読み込むのに使用する値であり、parentではそのWidgetの種類を記入します。(Widget名には、.(ドット)を記入しません。)
<?xml version="1.0" encoding="UTF-8"?>
<interface>
<template class="window" parent="GtkWindow">
</template>
</interface>
プロパティーの指定
対象のWidgetのプロパティは青字のように1項目ずつnameにプロパティ名を指定して、<property>と</property>の間にそのプロパティの値を記入します。
<?xml version="1.0" encoding="UTF-8"?>
<interface>
<template class="window" parent="GtkWindow">
<property name="default_width">450</property>
<property name="default_height">60</property>
<property name="title">Template Window Test</property>
</template>
</interface>
3. ウィンドウへの子Widget(Gtk.Box)の追加
作成したwindowに子Widgetを追加するには、以下のように追加したいWidgetの情報を<child></child>の中に記入します。
子Widgetの定義では、<object>の中に、class:子Widgetの種類とidを記入します。idは、python側でそのWidgetを呼び出すのに使用するものです。下の例では、<object></object>の中に子Widget(id=”box”)のプロパティを記入しています。
<?xml version="1.0" encoding="UTF-8"?>
<interface>
<template class="window" parent="GtkWindow">
<property name="default_width">450</property>
<property name="default_height">60</property>
<property name="title">Template Window Test</property>
<child>
<object class="GtkBox" id="box">
<property name="hexpand">True</property>
<property name="margin-bottom">10</property>
<property name="margin-end">10</property>
<property name="margin-start">10</property>
<property name="margin-top">10</property>
<property name="spacing">10</property>
<property name="vexpand">True</property>
</object>
</child>
</template>
</interface>
4. Gtk.Boxへの子Widgetの追加
子Widgetの追加方法
box(class:GtkBoxのid名)に子Widgetを追加する場合も、windowにboxを追加したのと同じように、追加したいWidgetの情報を<child></child>の中に記入します。複数の子Widgetを載せる場合は、それぞれ別の<child></child>の中にWidgetの情報を記入します。
複数の子Widgetを載せる場合、子Widgetは記入した順番にGtk.Boxに載せられます。
シグナルの追加方法
xmlファイル内でシグナルを定義する場合は、<signal name=’シグナル名’ hundler=’関数名’/>のように記入します。
<?xml version="1.0" encoding="UTF-8"?>
<interface>
<template class="window" parent="GtkWindow">
# 省略
<child>
<object class="GtkBox" id="box">
# 省略
<!--1つめのWidget: GtkLabel -->
<child>
<object class="GtkLabel" id="label">
<property name="label">Entryの文字を表示</property>
</object>
</child>
<!--1つめのWidget: GtkEntry -->
<child>
<object class="GtkEntry" id="entry">
</object>
</child>
<!--3つめのWidget: GtkButton -->
<child>
<object class="GtkButton" id="button">
<property name="label">押す</property>
<!-- シグナルの追加 -->
<signal name="clicked" handler="on_button_clicked"/>
</object>
</child>
</object>
</child>
</template>
</interface>
今回作成したXMLファイル
今回作成したXMLファイルは、以下の通りです。このファイルをPythonプログラムで使用する方法にについては、別途紹介します。
<?xml version="1.0" encoding="UTF-8"?>
<interface>
<template class="window" parent="GtkWindow">
<property name="default_width">450</property>
<property name="default_height">60</property>
<property name="title">Template Window Test</property>
<child>
<object class="GtkBox" id="box">
<property name="hexpand">True</property>
<property name="margin-bottom">10</property>
<property name="margin-end">10</property>
<property name="margin-start">10</property>
<property name="margin-top">10</property>
<property name="spacing">10</property>
<property name="vexpand">True</property>
<!--1つめのWidget: GtkLabel -->
<child>
<object class="GtkLabel" id="label">
<property name="label">Entryの文字を表示</property>
</object>
</child>
<!--1つめのWidget: GtkEntry -->
<child>
<object class="GtkEntry" id="entry">
</object>
</child>
<!--3つめのWidget: GtkButton -->
<child>
<object class="GtkButton" id="button">
<property name="label">押す</property>
<!-- シグナルの追加 -->
<signal name="clicked" handler="on_button_clicked"/>
</object>
</child>
</object>
</child>
</template>
</interface>