日別アーカイブ: 2023/04/23

Gtk.FileDialog

Gtk.FileDialog

GtkDialog 関連が廃止予定なので GTK+ 4.8 の間に置き換え。
と早めにしようとしたら GtkFileDialog が 4.10 にならないと用意されない。
ということでのんびり 4.10 を待っていたのは筆者だけではないと思う。

FileChooserDialog は GtkDialog ベース。
GtkDialog は GtkWindow ベース、更に GtkWidget ベース更に…
継承の仕組みとはいえ限られた用途な部品とは思えない作りだった。
GtkFileDialog は GObject からの単一継承と解りやすくなった。

いやそんな細かいことはどうでもいいですよね。
とっととサンプルコード。

#!/usr/bin/env python3

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

WRITE_TEXT = 'Python 文字列は UTF-8 に変換する'.encode('utf8')

class Win(Gtk.ApplicationWindow):
    '''
        GtkFileDialog: Sample Code
    '''
    def __init__(self, a):
        # Set Adwaita Style
        manager = Adw.StyleManager.get_default()
        manager.set_color_scheme(Adw.ColorScheme.DEFAULT)
        # init
        Gtk.ApplicationWindow.__init__(self, application=a)
        # Button
        button_open = Gtk.Button(label='_Open', use_underline=True)
        button_open.connect('clicked', self.on_button_open_clicked)
        button_save = Gtk.Button(label='_Save', use_underline=True)
        button_save.connect('clicked', self.on_button_save_clicked)
        button_old = Gtk.Button(label='_GtkFileChooserDialog', use_underline=True)
        button_old.connect('clicked', self.on_button_old_clicked)
        # box
        vbox = Gtk.Box(orientation=Gtk.Orientation.VERTICAL)
        vbox.append(button_open)
        vbox.append(button_save)
        vbox.append(button_old)
        self.set_child(vbox)

    def on_button_open_clicked(self, button):
        dlg = Gtk.FileDialog()
        dlg.open(self, None, self.on_open_dlg_callback)

    def on_open_dlg_callback(self, dlg, res):
        try:
            f = dlg.open_finish(res)
            print(f.get_path())
        except Exception as e:
            print('Cancel')

    def on_button_save_clicked(self, button):
        dlg = Gtk.FileDialog()
        dlg.save(self, None, self.on_save_dlg_callback)

    def on_save_dlg_callback(self, dlg, res):
        try:
            f = dlg.save_finish(res)
            stream = f.replace(None, False, Gio.FileCreateFlags.NONE)
            stream.write(WRITE_TEXT)
            stream.close()
        except Exception as e:
            print('Cancel')

    def on_button_old_clicked(self, button):
        dlg = Gtk.FileChooserDialog(title='Open', action=Gtk.FileChooserAction.OPEN, modal=True)
        dlg.add_buttons('_Cancel', Gtk.ResponseType.CANCEL, '_Open', Gtk.ResponseType.ACCEPT)
        dlg.set_transient_for(self)
        dlg.connect('response', self.on_open_dlg_response)
        # CSS CLASS
        dlg.get_widget_for_response(Gtk.ResponseType.ACCEPT).add_css_class('suggested-action')
        # Gtk.Widget.show() is deprecated
        dlg.set_visible(True)

    def on_open_dlg_response(self, dlg, response_id):
        if response_id == Gtk.ResponseType.ACCEPT:
            f = dlg.get_file()
            print(f.get_path())
        dlg.destroy()

app = Gtk.Application()
app.connect('activate', lambda a: Win(a).present())
app.run()

filedialog

GtkFileChooserDialog は GTK+ 4.10 でもエラーにはなりません。
AppKit|UIKit 同様に廃止予定にして頃合で削除するみたい。

open と save の振り分けはプロパティではなく関数になりました。
複数選択の指定も関数になったけど説明はいらないよね。
シグナルではなくコールバック関数にて処理だけどあまり変わらない。
GtkDialog とは違い自前で破棄する必要は無くなったようです。

open file

ACCEPT ボタンは CSS 指定せずとも勝手に青くなります。
GtkFileFilter は default-filter プロパティで指定可能。
後は公式を見れば使い方は解ると思う。

ついでに気がつく、Gtk.Widget.show|hide も廃止なんだね。
visible プロパティと被っていたし整理したのかな。

ところで WordPress のアップロードがこの FileDialog になった。
複数選択ができないんですけど、一個づつアップロードするのメンドイ。

ということで我が Comipoli も更新しようと思ったのですが。
svg アイコンが摘要されない、128×128 強制になったのだろうか?
現在 Boxy SVG というアプリと格闘中、ということで。

kiji

昨日今日と夏鳥を求めて歩き回って成果はゼロ。
キジなら何故か簡単に見つかってこんなカッコイイ写真が撮れるのに。
筆者は今年も夏鳥とは相性が悪いのか。。。。。