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

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

 Gtk.FileDialogは、Gtk4.10より新たに追加されたファイルを選択するのに使用するダイアログです。
Gtk.FileDialogはXLMデータによって作成することだけでなく、その他にも表示する拡張子の指定もおこなうことができます。

 今回は、XMLデータでGtk.FileDialogを作成する方法とGtk.FileDialogに表示するファイルの拡張子を指定する方法について紹介します。

今回紹介する内容
 ・ XMLデータでGtk.FileDialogを作成する
 ・ XMLデータでGtk.FileDialogのフィルタを定義する
 ・ XMLデータでフィルタで複数の拡張子を有効にする

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

XMLデータでGtk.FileDialogを作成する

 Gtk.FileDialogの定義は以下のように記入します。

 ・ </template>と</interface>の間に記入する。
 ・ <object class=”GtkFileDialog” id=”(id名)”>と</object>を書き、
   その間にプロパティなどを記入する。
 ※ 今回はフィルタ機能を使用するので、default-filterとfiltersを設定しています。

       </object>
    <object class="GtkFileDialog" id="filedialog">
        <property name="default-filter">filter1</property>
        <property name="filters">filters</property>
    </object>
</interface>

XMLデータでGtk.FileDialogのフィルタを定義する

 Gtk.FileDialogのフィルタはGio.ListModelですが、Gio.ListModelを継承したGio.ListStoreを使用して定義します。
 ・ </template>と</interface>の間に記入する。
 ・ Gio.ListStoreを定義する<object class=”GListStore” id=”フィルタ達の名前”>と</object>の
   中にフィルタ情報を記入する。
   ※ ここで定義したidを、Gtk.FIleDialogの定義時に指定します。
 ・ Gtk.ListFilterは、<object class=”GtkFileFilter” id=”フィルタ名”>で定義します。
 ・ Gtk.ListFilterでは、プロパティnameで画面に表示するフィルタ名を指定して、
   プロパティpatternsやmime-typesやsuffixesによりファイル内容を指定します。

    <object class="GListStore" id="filters">
        <child>
            <object class="GtkFileFilter" id="filter1">
                <property name="name">htmlファイル</property>
                <property name="patterns">*.html</property>
            </object>
        </child>
        # 省略
    </object>

XMLデータでフィルタで複数の拡張子を有効にする

 1つのGtk.ListFilterで複数の拡張子が対象(例:’*.txt’と’*.text’が有効)のフィルタを作成する場合は、以下のように<patterns>と</patterns>の中に<pattern>と</pattern>で挟んだものを、1つずつ定義します。

        <child>
            <object class="GtkFileFilter" id="filter2">
                <property name="name">textファイル</property>
                <patterns>
                    <pattern>*.txt</pattern>
                    <pattern>*.text</pattern>
                </patterns>
            </object>
        </child>

サンプルプログラム

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

実行方法

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

python main.py
<?xml version="1.0" encoding="UTF-8"?>
<interface>
    <template class="window" parent="GtkApplicationWindow">
        <property name="default_width">400</property>
        <property name="default_height">80</property>
        <property name="title">Template FileDialog Test</property>
        <child>
            <object class="GtkButton" id="button">
                <property name="margin_top">20</property>
                <property name="margin_bottom">20</property>
                <property name="margin_start">20</property>
                <property name="margin_end">20</property>
                <property name="label">Gtk.FileDialog呼び出し</property>
                <signal name="clicked" handler="on_button_clicked"/>
            </object>
        </child>
    </template>
    <object class="GListStore" id="filters">
        <child>
            <object class="GtkFileFilter" id="filter1">
                <property name="name">htmlファイル</property>
                <property name="patterns">*.html</property>
            </object>
        </child>
        <child>
            <object class="GtkFileFilter" id="filter2">
                <property name="name">textファイル</property>
                <patterns>
                    <pattern>*.txt</pattern>
                    <pattern>*.text</pattern>
                </patterns>
            </object>
        </child>
        <child>
            <object class="GtkFileFilter" id="filter3">
                <property name="name">xmlファイル</property>
                <property name="patterns">*.xml</property>
            </object>
        </child>
    </object>
    <object class="GtkFileDialog" id="filedialog">
        <property name="default-filter">filter1</property>
        <property name="filters">filters</property>
    </object>
</interface>
# -*- coding: utf-8 -*-

import gi
import os
import logging
gi.require_version('Gtk', '4.0')
from gi.repository import Gtk, Gio, GLib  # noqa E402


logging.basicConfig(
    level=logging.DEBUG, format='[%(levelname)s]: %(message)s')

logging.disable(logging.CRITICAL)

APPID = 'com.github.taniyoshima.g4_fblogt_filedialog'


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

    filedialog = Gtk.Template.Child()

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

    @Gtk.Template.Callback()
    def on_button_clicked(self, button):
        cancellable = Gio.Cancellable.new()

        self.filedialog.open_multiple(
            parent=self, cancellable=cancellable,
            callback=self.on_filedialog_open_multiple)

    def on_filedialog_open_multiple(self, filedialog, task):
        try:
            files = filedialog.open_multiple_finish(task)
        except GLib.GError:
            return

        for file in files:
            if os.path.isfile(file.get_path()):
                print(file.get_path())
                print(file.get_parent().get_path())
                print(file.get_basename())


class Gtk4TestApp(Gtk.Application):

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

    def do_startup(self):
        Gtk.Application.do_startup(self)

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


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


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