[Gtk.Template]Gtk.Dialogの使用について

XMLデータにより定義したGtk.Dialogの使用

 Gtk.Dialogは、Gtk4.10より非推奨となりましたが、Gtk4の間は使用することが可能です。(代替Widgetは、Gtk.Windowです。) 

 Gtk.DialogをXMLデータで定義する方法を紹介します。定義したGtk.Dialogの表示・非表示、追加したボタンの処理方法についても紹介します。

XMLデータでのGtk.Dialogの記入

 Gtk.Dialogの作成は以下のように記入します。

 ・ </template>と</interface>の間に記入する。
 ・ <object class=”GtkDialog” id=”(id名)”>と</object>を書き、
   その間にプロパティなどを記入する。
 ・ プロパティtransient-forの値は、id名で指定します。

    </template>
    <object class="GtkDialog" id="dialog">
        <property name="default_width">200</property>
        <property name="default_height">200</property>
        <property name="transient_for">window</property>
        …省略…
    </object>
</interface>

Gtk.Dialogのコンテンツエリアに載せるものを作成する。

 Gtk.DialogのコンテンツエリアにXMLデータでWidgetを載せるのには、以下のように記入します。

    <object class="GtkDialog" id="dialog">
       …省略…
        <child internal-child="content_area">
            <object class="GtkBox" id="dbox">
                <child>
                    <object class="GtkLabel" id="dlabel">
                        <property name="label">ダイアログ</property>
                        <property name="vexpand">True</property>
                    </object>
                </child>
            </object>
        </child>
       …省略…
    </object>
</interface>

Gtk.Dialogのボタンを作成する。

 Gtk.Dialogのボタンは、以下のように作成します。
 1. <child type=”action”></child>内にボタン内容を記入する。
 2. <action-widgets></action-widgets>内にActionを記入して、ボタンと紐付ける。

    <object class="GtkDialog" id="dialog">
       …省略…
        <child type="action">
            <object class="GtkButton" id="button_cancel">
                <property name="label">キャンセル</property>
            </object>
        </child> <child type="action">
            <object class="GtkButton" id="button_ok">
                <property name="label">OK</property>
            </object>
        </child>
        <action-widgets>
            <action-widget response="cancel">button_cancel</action-widget>
            <action-widget response="ok" default="true">button_ok</action-widget>
        </action-widgets>
    </object>

Gtk.Dialogのボタンを押した場合の処理を記入する。

 Gtk.Dialogのボタンが押された場合の処理を指定するため、シグナル’response’と関数on_dialog_responseを紐付けます。

        <signal name="response" handler="on_dialog_response"/>

 関数on_dialog_responseでは、response_idから押されたボタン情報を取得して、押したボタンにあった動作を指定することができます。

    @Gtk.Template.Callback()
    def on_dialog_response(self, dialog, response_id):
        if response_id == Gtk.ResponseType.OK:
            print('OK を押しました。')
        elif response_id == Gtk.ResponseType.CANCEL:
            print('キャンセル を押しました。')
        else:
            print('Esc もしくは☓を押しました。')

        dialog.set_visible(False)

Gtk.Dialogを表示する

 Gtk.Dialogの表示・非表示は、メソッドset_visible()により指示します。

    @Gtk.Template.Callback()
    def on_button_clicked(self, button):
        self.dialog.set_visible(True)

サンプルプログラム

 以下のサンプルプログラムを実行すると左図のようなボタン(Dialog表示)付きのWindowが表示されます。ボタンを押すと、右図のようなGtk.Dialogが表示されます。

実行方法

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

python main.py
<?xml version="1.0" encoding="UTF-8"?>
<interface>
    <template class="window" parent="GtkWindow">
        <property name="default_width">500</property>
        <property name="default_height">70</property>
        <property name="title">Template Dialog Test</property>
        <child>
            <object class="GtkButton" id="button">
                <property name="label">Dialog 表示</property>
                <property name="margin_top">20</property>
                <property name="margin_bottom">20</property>
                <property name="margin_start">20</property>
                <property name="margin_end">20</property>
                <signal name="clicked" handler="on_button_clicked"/>
            </object>
        </child>
    </template>
    <object class="GtkDialog" id="dialog">
        <property name="default_width">200</property>
        <property name="default_height">200</property>
        <property name="transient_for">window</property>
        <signal name="response" handler="on_dialog_response"/>
        <child internal-child="content_area">
            <object class="GtkBox" id="dbox">
                <child>
                    <object class="GtkLabel" id="dlabel">
                        <property name="label">ダイアログ</property>
                        <property name="vexpand">True</property>
                    </object>
                </child>
            </object>
        </child>
        <child type="action">
            <object class="GtkButton" id="button_cancel">
                <property name="label">キャンセル</property>
            </object>
        </child> <child type="action">
            <object class="GtkButton" id="button_ok">
                <property name="label">OK</property>
            </object>
        </child>
        <action-widgets>
            <action-widget response="cancel">button_cancel</action-widget>
            <action-widget response="ok" default="true">button_ok</action-widget>
        </action-widgets>
    </object>
</interface>
import os
import gi
gi.require_version('Gtk', '4.0')
from gi.repository import Gtk


APPID = 'com.github.taniyoshima.g4_fblogt_dialog'


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

    dialog = Gtk.Template.Child()

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

    @Gtk.Template.Callback()
    def on_button_clicked(self, button):
        self.dialog.set_visible(True)

    @Gtk.Template.Callback()
    def on_dialog_response(self, dialog, response_id):
        if response_id == Gtk.ResponseType.OK:
            print('OK を押しました。')
        elif response_id == Gtk.ResponseType.CANCEL:
            print('キャンセル を押しました。')
        else:
            print('Esc もしくは☓を押しました。')

        dialog.set_visible(False)


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をコピーしました