[Gtk.Template] XMLデータの使用

PyObjectにXMLデータを読み込ませる

 前回は、PyObjectに読み込ませるXMLデータ(GtkBuilder UI Definition XML Document)の記入方法について紹介しました。XMLデータは、Gtk4ではPythonファイルに埋め込むこともできますし、XMLファイルとしてPythonファイルとは別に作成して、そのXMLファイルを読み込む形で使用することもできます。
 今回は、①使用するXMLデータの保存方法(Pythonファイルに埋め込むか、XMLファイルに保存する)と、②作成したXMLデータをPyObjectで読み込んでインターフェイスを表示する方法について紹介します。

※ XMLファイルの記入方法については以下で紹介しています。

使用するXMLデータの保存方法

 Gtk4では、XMLデータを①Pythonファイル内に埋め込んだり、②XMLファイルに記入してそれを読み込んで使用することができます。それらの記入方法は以下の通りです。

Pythonファイル内に埋め込む

 Pythonファイルに埋め込む場合は、XMLデータをxml =””” と”””との間に記入します。


xml = """\
<?xml version="1.0" encoding="UTF-8"?>
<interface>
  # 省略
</interface>
"""

XMLファイルに記入して

 XMLファイルに記入する場合は、ファイルの中にXMLデータをそのまま記入します。

<?xml version="1.0" encoding="UTF-8"?>
<interface>
  # 省略
</interface>

作成したXMLデータをPyObjectで読み込む

 作成したXMLデータをPyObjectで読み込み使用するには、以下の作業をおこなう必要があります。
 ・ XMLデータを読み込みインターフェースを作成する。
 ・ XMLデータで定義したWidgetをPython側で使用できるように紐付ける。
 ・ XMLデータで定義した関数をPython側のものと紐付ける。

XMLデータを読み込みインターフェースを作成する。

 Widget(下の場合、Gtk.Window)のサブクラスに、PyObjectでXMLデータを読み込みインターフェースを作成するには、以下のように記入します。

  1. @Gtk.Template() デコレーターで、読み込むXMLデータを指定します。
  2. クラス変数__gtyple_name__に、サブクラスのWidgetに対応するXMLデータでのclassを指定します。
# Pythonファイル内に埋め込んだ場合
@Gtk.Template(string=xml)
class Gtk4TestTest(Gtk.Window):
    __gtype_name__ = "window"
# XMLファイル(ファイル名:ui_file.ui)に記入した場合
@Gtk.Template(filename=os.path.dirname(__file__) + '/ui_file.ui')
class Gtk4TestTest(Gtk.Window):
    __gtype_name__ = "window"

 @Gtk.Template() で使用可能な引数は以下の3つであり、XMLデータの保存形式に合わせて指定します。

名前内容
stringデータをPythonファイルに記入した文字列(XML)から取得する場合に使用する。
filenameデータをXMLファイルから取得する場合に使用する。
resource_pathデータをGio.Resourceから取得する場合に使用する。
@Gtk.Template()の引数

※ resource_pathについては、Gio.Resourceの使用方法で説明する予定です。

XMLデータで作成したWidgetをPython側で使用できるように紐付ける。

 XMLデータ内で定義したWidgetを利用するには、以下のようにXMLデータで作成したWidgetとPython側のクラス変数とを紐付けます。XMLデータ内のidと変数名が違う場合は、Gtk.Template(‘id名’)のようにidを指定します。

@Gtk.Template(string=xml)
class Gtk4TestTest(Gtk.Window):
    __gtype_name__ = "window"

    entry = Gtk.Template.Child()

XMLデータで定義した関数をPython側のものと紐付ける。

 XMLデータ内で定義した関数を記入するには、Python側にXMLデータで定義した関数と同じ名前の関数を作成して、その前にデコレーター(@Gtk.Template.Callback())をつけます。

    @Gtk.Template.Callback()
    def on_button_clicked(self, button):
        text = self.entry.get_text()
        print('entryの文字は、{}です。'.format(text))

サンプルプログラム

① プログラム内に記入したXMLデータを読み込む

 下記サンプルプログラムでは、埋め込んだXMLデータを読み込み実行します。

プログラムの実行方法

 ファイルを任意のフォルダに保存して、そのフォルダで以下のコマンドを実行します。

python main.py
import os
import gi
gi.require_version('Gtk', '4.0')
from gi.repository import Gtk


APPID = 'com.github.taniyoshima.g4_fblogt_window1'

xml = """\
<?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 Test2</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>
                <child>
                    <object class="GtkLabel" id="label">
                        <property name="label">Entryの文字を表示</property>
                    </object>
                </child>
                <child>
                    <object class="GtkEntry" id="entry">
                    </object>
                </child>
                <child>
                    <object class="GtkButton" id="button">
                        <property name="label">押す</property>そのフォルダで
                        <signal name="clicked" handler="on_button_clicked"/>
                    </object>
                </child>
            </object>
        </child>
    </template>
</interface>
"""


@Gtk.Template(string=xml)
class Gtk4TestTest(Gtk.Window):
    __gtype_name__ = "window"

    entry = Gtk.Template.Child()

    def __init__(self, app):
        Gtk.Window.__init__(
            self, application=app)

    @Gtk.Template.Callback()
    def on_button_clicked(self, button):Gio.Resource
        text = self.entry.get_text()
        print('entryの文字は、{}です。'.format(text))


class Gtk4TestApp(Gtk.Application):

    def __init__(self):
        Gtk.Application.__init実行方法

 下の2つのファイルを同じフォルダに保存して、以下のコマンドを実行します。

python main.py__(self, application_id=APPID)

    def do_activate(self):
        window = Gtk4TestTest(self)
        window.present()ログラムの実行方法

 下の2つのファイルを同じフォルダに保存して、以下のコマンドを実行します。




def main():
    app = Gtk4TestApp()
    app.run()


if __name__ == '__main__':
    main()

② XMLファイルからデータを読み込む

 下記サンプルプログラムでは、同じフォルダに保存したXMLファイル(ui_file.ui)を読み込み、それをもとに作成したインターフェイスを表示します。

プログラムの実行方法

 下の2つのファイルを同じフォルダに保存して、そのフォルダで以下のコマンドを実行します。

python main.py
<?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 Test2</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>
                <child>
                    <object class="GtkLabel" id="label">
                        <property name="label">Entryの文字を表示</property>
                    </object>
                </child>
                <child>
                    <object class="GtkEntry" id="entry">
                    </object>
                </child>
                <child>
                    <object class="GtkButton" id="button">
                        <property name="label">押す</property>
                        <signal name="clicked" handler="on_button_clicked"/>
                    </object>
                </child>
            </object>
        </child>
    </template>
</interface>
import os
import gi
gi.require_version('Gtk', '4.0')
from gi.repository import Gtk


APPID = 'com.github.taniyoshima.g4_fblogt_window2'


@Gtk.Template(filename=os.path.dirname(__file__) + '/ui_file.ui')
class Gtk4TestTest(Gtk.Window):
    __gtype_name__ = "window"

    entry = Gtk.Template.Child()

    def __init__(self, app):
        Gtk.Window.__init__(
            self, application=app)

    @Gtk.Template.Callback()
    def on_button_clicked(self, button):
        text = self.entry.get_text()
        print('entryの文字は、{}です。'.format(text))


class Gtk4TestApp(Gtk.Application):

    def __init__(self):
        Gtk.Application.__init__(self, application_id=APPID)

    def do_activate(self):
        window = Gtk4TestTest(self)
        window.present()


def main():
    app = Gtk4TestApp()
    app.run()


if __name__ == '__main__':
    main()
タイトルとURLをコピーしました