[Python,Gtk4] Gtk.FileChooserDialogの使用について① ファイルを開く、ファイルを保存する

Gtk.FileChooserDialogの使用

 Gtk.FileChooserDialogは、ファイルを開く、ファイルを閉じる、フォルダを開く作業を行うためのWidgetの1つです。Gtk.FileChooserDialogは、Gtk4.10より非推奨となりましたが、Gtk4では引き続き利用することが可能です。Gtk.FileChooserDialogの代替Widgetは、GtkFileDialogです。

 今回は、Gtk.FileChooserDialogでファイルを開く方法とGtk.FileChooserDialogにフィルタを設定する方法について紹介します。

今回紹介する内容
 ・ Gtk.FileChooserDialogを作成する
 ・ Gtk.FileChooserDialogのアクション領域へボタンを追加する
 ・ Gtk.FileChooserDialogに追加したボタンの処理を追加する
 ・ Gtk.FileChooserDialogに表示するファイル種類を限定する(フィルタ)

Gtk.FileChooserDialogの作成

Gtk.FileChooserDialogを作成する

 Gtk.FileChooserDialogの以下のように作成します。

        dialog = Gtk.FileChooserDialog(
            title="ファイルを開く",
            transient_for=self,
            action=Gtk.FileChooserAction.OPEN
        )

 今回のサンプルプログラムで使用したプロパティは、以下のとおりです。

内容
actionGtk.FileChooserActionGtk.FileChooserのタイプを指定する。
タイプの種類は、次を参照。
titlestrWindowのタイトルを指定する。
※ Gtk.Windowのプロパティ
transient_forGtk.Windowウィンドウの一時的な親を指定する。modalを使用するのに使用する。
サンプルプログラムは、selfを使用することでGtk.Windowを指定している。
※ Gtk.Windowのプロパティ
modalboolモーダルにするかどうかを指定する。Trueの場合、モーダルとなり、サンプルプログラムでは、Gtk.MessageDialogは常にGtk.Windowの前に表示される。
※ Gtk.Windowのプロパティ

Gtk.FileChooserDialogActionの種類

 Gtk.FileChooserDialogActionには以下の3つがあり、この値を指定することでGtk.FileChooserDialogが何をするためのものかを指定します。

内容
OPEN既存のファイルのみを選択できるモード
ファイルを開くのに使用する。
SAVE既存のファイルを選択するか、新しいファイル名を入力できるモード
ファイルの保存に使用する。
SELECT_FOLDERフォルダーを選択するためのモード
開くファイルを選択するのに使用する。
Gtk.FileChooserDialogActionの種類

Gtk.FileChooserDialogのアクション領域へボタンを追加する

 Gtk.FileChooserDialogへのボタンの追加には、メソッドadd_buttonやadd_buttonsを使用します。以下の例では、メソッドadd_buttonを使用して’キャンセル’と’OK’ボタンを追加しています。 

        # Gtk.FileChooserDialogへのボタンの追加(キャンセル、OK)
        dialog.add_button('キャンセル', Gtk.ResponseType.CANCEL)
        dialog.add_button('OK', Gtk.ResponseType.OK)

Gtk.FileChooserDialogに追加したボタンの処理を追加する

 Gtk.FileChooserDialogも、Gtk.Dialogと同じように、①’response’とボタンを実行する関数とを紐付け、②実行する関数内で押したボタンを判定して、ボタンごとの動作を指示します。

 Gtk.Dialogに追加したボタンの処理

選択したファイル情報の取得

 Gtk.FileChooserDialogで選択したファイルの情報を取得するには、以下の作業をおこないます。
 1. Gtk.FileChooserのメソッドget_file()により、Gtk.FileChooserDialogで選択した
   ファイルを取得する。 返り値:Gio.File or None
 2.  Gio.Fileのメソッドget_path()によりパス付きのファイル名を、メソッドget_basename()
   によりファイル名のみを取得する。

    # シグナル'response'と関数on_dialog_responseとを紐付け
    dialog.connect('response', self.on_dialog_response)

   -----------------------------------------

    def on_dialog_response(self, dialog, response_id):
        if response_id == Gtk.ResponseType.OK:
            file = dialog.get_file()
            print('選択ファイルの名(パス付き)' + file.get_path())
            print('選択ファイルの名(ファイル名のみ)' + file.get_basename())
        dialog.destroy()

Gtk.FileChooserDialogに表示するファイル種類を限定する(フィルタ)

 Gtk.FileChooserDialogへのフィルタの追加は、以下の手順でおこないます。
 1. Gtk.FileFilterを定義する。
 2. Gtk.FileFilterのメソッドset_name()により、人が判別できる名前をつける。
 3. Gtk.FileFilterのメソッドadd_mime_type()により、表示を許可するMIMEタイプを指定する。
 4. Gtk.FileChooserDialogのメソッドadd_filter()により、作成したフィルタを追加する。

    def add_filters(self, dialog):
        filter_text = Gtk.FileFilter()
        filter_text.set_name("Text files")
        filter_text.add_mime_type("text/plain")
        dialog.add_filter(filter_text)

        ・・・省略・・・

 表示を許可するファイルの指定は、メソッドadd_mime_type()の他にもadd_pattern()やadd_suffix()により指定できます。

サンプルプログラム

 以下のサンプルプログラムを実行すると、2つのボタンを持ったウィンドウが表示されます。それぞれのボタンを押すと、ボタンのラベルにあったGkt.FileChooserDialogが表示されます。

 Gtk.FileChooserDialogでファイルを選択して「Ok」を押すと、選択したファイルの名前とパスがターミナルに表示されます。

import gi
gi.require_version('Gtk', '4.0')
from gi.repository import Gtk


APPID = 'com.github.taniyoshima.filechooserdialog'


class Gtk4TestTest(Gtk.Window):

    def __init__(self, app):
        Gtk.Window.__init__(
            self, application=app, title='FileChooserDialog Test')

        box = Gtk.Box(
            margin_top=30, margin_bottom=30,
            margin_start=30, margin_end=30,
            width_request=350, height_request=250,
            orientation=Gtk.Orientation.VERTICAL,
            spacing=10
        )

        button1 = Gtk.Button(label='ファイルを開く', hexpand=True)
        button1.connect('clicked', self.on_button1_clicked)

        button2 = Gtk.Button(label='ファイルを保存する', hexpand=True)
        button2.connect('clicked', self.on_button2_clicked)

        box.append(button1)
        box.append(button2)

        self.set_child(box)

    def on_button1_clicked(self, button):
        dialog = Gtk.FileChooserDialog(
            title="ファイルを開く",
            transient_for=self,
            modal=True,
            action=Gtk.FileChooserAction.OPEN
        )
        # Gtk.FileChooserDialogへのボタンの追加(キャンセル、OK)
        dialog.add_button('キャンセル', Gtk.ResponseType.CANCEL)
        dialog.add_button('OK', Gtk.ResponseType.OK)

        # シグナル'response'と関数on_dialog_responseとを紐付け
        dialog.connect('response', self.on_dialog_response)

        self.add_filters(dialog)

        # Gtk.Dialogの表示
        dialog.show()

    def add_filters(self, dialog):
        filter_text = Gtk.FileFilter()
        filter_text.set_name("Text files")
        filter_text.add_mime_type("text/plain")
        dialog.add_filter(filter_text)

        filter_py = Gtk.FileFilter()
        filter_py.set_name("Python files")
        filter_py.add_mime_type("text/x-python")
        dialog.add_filter(filter_py)

        filter_any = Gtk.FileFilter()
        filter_any.set_name("Any files")
        filter_any.add_pattern("*")
        dialog.add_filter(filter_any)

    def on_dialog_response(self, dialog, response_id):
        if response_id == Gtk.ResponseType.OK:
            file = dialog.get_file()
            print('選択ファイルの名(パス付き)' + file.get_path())
            print('選択ファイルの名(ファイル名のみ)' + file.get_basename())
        dialog.destroy()

    def on_button2_clicked(self, button):
        dialog = Gtk.FileChooserDialog(
            title="ファイルの保存",
            transient_for=self,
            modal=True,
            action=Gtk.FileChooserAction.SAVE,
        )
        # Gtk.FileChooserDialogへのボタンの追加(キャンセル、OK)
        dialog.add_button('キャンセル', Gtk.ResponseType.CANCEL)
        dialog.add_button('OK', Gtk.ResponseType.OK)

        # シグナル'response'と関数on_dialog_response2とを紐付け
        dialog.connect('response', self.on_dialog_response2)

        self.add_filters(dialog)

        # Gtk.Dialogの表示
        dialog.show()

    def on_dialog_response2(self, dialog, response_id):
        if response_id == Gtk.ResponseType.OK:
            files = dialog.get_files()
            for file in files:
                print('選択ファイル名(パス付き)' + file.get_path())
                print('選択ファイル名(ファイル名のみ)' + file.get_basename())
        dialog.destroy()


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