Programming」カテゴリーアーカイブ

Fedora 36 Install

Fedora 36 が出ました。
早速 SSD を交換してインストール、今までと同じです。
初期状態を確認したいだけです、新規にする必要はないとは言わないで。

Nautilus のアイコンが青色ベースに変わっている。
でもメニューを見ると GTK3 のままなのか。
F10 でロケーションバーがドロップダウンに、何この挙動?

Gedit は無くなり gnome-text-editor に代わった。
メニューが日本語翻訳され設定が別ウインドウに変更されました。
でもスニペットや外部ツールてかプラグインは使えません。
コレについては後日色々と、筆者は Gedit を入れますけど。

設定は GTK4 化されていますね。
あと gnome-softwere 等の gnome-*** な純正アプリは。
eog 等の半純正は GTK3 のままみたい、GTK3 の時と違って慎重のようで。

そんなことよりコレですよね。

2022.05.22 修正

#!/usr/bin/env python3

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

a = Gtk.get_major_version()
b = Gtk.get_minor_version()
c = Gtk.get_micro_version()
print(f'GTK+ version {a}.{b}.{c}')

'''
# Fedora 35
GTK+ version 4.4.2

# Fedora 36
GTK+ version 4.6.2
'''

マイナーバージョンだけかよ。
でもコレはイケるかな?

python 3.x – Drag and drop with GTK4: connecting DragSource and DropTarget via ContentProvider for derived classes – Stack Overflow

#!/usr/bin/env python3

# https://stackoverflow.com/questions/70921068/drag-and-drop-with-gtk4-connecting-dragsource-and-droptarget-via-contentprovide
# GDK_TYPE_FILE_LIST
 
import gi, sys
gi.require_version('Gtk', '4.0')
gi.require_version('Gdk', '4.0')
from gi.repository import Gtk, Gio, Gdk, GObject

class Win(Gtk.ApplicationWindow):
    '''
        GtkGestureDrag Sample Code
    '''
    def __init__(self, app):
        try:
            Gtk.ApplicationWindow.__init__(self, application=app, title='Drop FIle')
            drop_target = Gtk.DropTarget.new(Gdk.FileList, Gdk.DragAction.COPY)
            drop_target.connect('drop', self.on_file_drop)
            drop_target.connect('accept', self.on_drop_accept)
            self.add_controller(drop_target)
            #
            self.label = Gtk.Label(label='Please drop the file')
            self.set_child(self.label)
        except Exception as e:
            print(e, file=sys.stderr)
            app.quit()

    def on_drop_accept(self, target, drop):
        return True

    def on_file_drop(self, target, value, x, y):
        l = []
        for gfile in value.get_files():
            l.append(gfile.get_path())
        self.label.set_text('\n'.join(l))

def app_activate(a):
    w = Win(a)
    w.present()

app = Gtk.Application()
app.connect('activate', app_activate)
app.run()

fedora36_dnd

gir でファイルドロップができるようになりました。

てかコレで気がついたけど gnome-screenshot が無くなっている。
代わりに Print Screen で範囲指定スクリーンショットが可能になった。
「~/画像/スクリーンショット」に保存される、いや OS 統合はいいと思う。
macOS だってそうなのだから、ね。

HDD マウント等でパスワード画面になると ibus が落ちて日本語が入力不能に。
時々再起動に失敗し電源ボタン長押しで強制終了。
いやー久々に細かい所が不安定だ、何故か喜んでいる筆者であった。

そうだ手動アップデートしなきゃ、イッパイあった。
夜勤準備でもう寝ます、続きは明日にでも。

GTK4: ActionBar and CenterBox

GTK4 は CenterBox という Widget が追加された。
説明を見ると GTK3 にあった ActionBar みたいなものか。
って ActionBar は GTK4 にも残っているんですけど。

Gtk.ActionBar

Gtk.CenterBox

ActionBar の CSS Node には Revealer というものがある。
これは Gtk::Revealer ではなく単純に表示と非表示の切り替えみたい。
Widget::show では何か都合が悪かったのだろうか?
ちなみに HeaderBar と違うのは背景透過であること。
フルスクリーンで使おうとしたけど背景が無くて文字列が読めないんでパス。

対する CenterBox は Widget ベースな単一ノード。
Gtk::Orientable インプリメントなので縦にもできるようだ。
でも縦に並んだ Widget で中心に何か置きたいという状況が思いつかない。

そういえば ButtonBox はとうとう無くなったな。
これの代わりってことかも、試してみよう。

#!/usr/bin/env python3

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

class Win(Gtk.ApplicationWindow):
    '''
        GTK4: Sample Code
    '''
    def __init__(self, a):
        Gtk.ApplicationWindow.__init__(self, application=a, title='GTK4')
        buttons = [Gtk.Button(label=f'Button{i+1}', hexpand=True) for i in range(6)]
        # ActionBar
        bar = Gtk.ActionBar()
        bar.pack_start(buttons[0])
        bar.set_center_widget(buttons[1])
        bar.pack_end(buttons[2])
        # CenterBox
        box = Gtk.CenterBox()
        box.set_start_widget(buttons[3])
        box.set_center_widget(buttons[4])
        box.set_end_widget(buttons[5])
        #
        vbox = Gtk.Box(orientation=Gtk.Orientation.VERTICAL)
        vbox.append(bar)
        vbox.append(box)
        self.set_child(vbox)
        self.set_default_size(400, 1)

def app_activate(a):
    w = Win(a)
    w.present()

app = Gtk.Application()
app.connect('activate', app_activate)
app.run()

centerbox

hexpand を指定してみたけど、引き伸ばされるのは共にセンターのみ。
ButtonBox のように等間隔に引き伸ばされると思ったけど違っていた。

違うのは ActionBar は挿入した Widget の回りに隙間ができるかどうか、のみ。
HeaderBar のよう Button を置きたいなら ActionBar を。
ステータスバーのように Label を置きたいなら CenterBox を。
という感じか。
まったくベースは違うけどあまり使い道は変わらない。

GTK4: ShortcutAction

前回 Gtk::Shortcut で SignalAction や ActivateAction を使いました。
これらは ShortcutAction のサブクラス、それらから必要なものを選びます。
名前でどういう用途かはだいたい解りますよね。

Gtk.ShortcutAction

その ShortcutAction の関数を見ると activate という関数がある。
第二引数に指定した Widget に activate を送る命令みたい、コレはもしかして!
GTK4 で排除された「ボタンをコードで模擬クリック」をコイツで賄えるかも。

#!/usr/bin/env python3

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

class Win(Gtk.ApplicationWindow):
    '''
        GTK4: Sample Code
    '''
    def __init__(self, a):
        Gtk.ApplicationWindow.__init__(self, application=a, title='GTK4')
        # Action
        self.act_action = Gtk.ActivateAction()
        # Button
        b1 = Gtk.Button(label='Button1')
        b1.connect('clicked', self.on_button1_clicked)
        self.b2 = Gtk.Button(label='Button2')
        self.b2.connect('clicked', self.on_button2_clicked)
        box = Gtk.Box(orientation=Gtk.Orientation.VERTICAL)
        box.append(b1)
        box.append(self.b2)
        self.set_child(box)

    def on_button1_clicked(self, widget):
        print('Button1 Clicked!')
        self.act_action.activate(Gtk.ShortcutActionFlags.EXCLUSIVE, self.b2)

    def on_button2_clicked(self, widget):
        print('Button2 Clicked!')

def app_activate(a):
    w = Win(a)
    w.present()

app = Gtk.Application()
app.connect('activate', app_activate)
app.run()

Button1 を押すと Button2 も押されることが GUI でも確認できるはず。
なるほど、コードで模擬クリックがしたいならこの手段が使えます。
第一引数は固定なので存在理由が不明ですが今後増えるかも、ということで。
本来の使い方では無いのでしょうけど、使い道は多かったりします。

GTK4: Shortcut

GTK4 には ShortcutController というものがあった。
あれ?筆者は以前嘘を書いてしまったのかな??

Gtk.ShortcutController

そう思って調べてみるとコレはアプリ全体のショートカット指定ではない。
Widget 毎にショートカットを設定するものってことみたい。
何が違うんだよって感じはしなくはないですけど。

#!/usr/bin/env python3

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

class Win(Gtk.ApplicationWindow):
    '''
        GTK4: Sample Code
    '''
    def __init__(self, a):
        Gtk.ApplicationWindow.__init__(self, application=a, title='GTK4')
        # Shortcut
        t = Gtk.ShortcutTrigger.parse_string('<Control>Z')
        a = Gtk.SignalAction(signal_name='clicked')
        s = Gtk.Shortcut(trigger=t, action=a)
        c = Gtk.ShortcutController()
        c.add_shortcut(s)
        # Button
        b = Gtk.Button(label='Test')
        b.connect('clicked', self.on_button_clicked)
        b.add_controller(c)
        self.set_child(b)

    def on_button_clicked(self, widget):
        print('Clicked!')

def app_activate(a):
    w = Win(a)
    w.present()

app = Gtk.Application()
app.connect('activate', app_activate)
app.run()

こんな感じ。

これで Ctrl+z でも clicked シグナルを発生できます。
ところで公式は GtkBuilder 形式にて activate を指定しています。

a = Gtk.ActivateAction()

でもいいです、こちらだとボタンが押された GUI アクションを行なわれます。
ただ activate と clicked 両方のシグナルが発生しますので扱いに注意。

ということでゴールデンウイークラストは花。

poppy

フラワーパーク江南にてシャーレーポピーが満開です。
くーるまにポピー♪って古い!

poppy

日本語名はヒナゲシです。
おっかのうえヒーナゲシのはーなでー♪だから古い!

sirotumekusa

一面にシロツメクサが咲き誇っています。
シロツメクサの♪花が咲いたら♪さあ♪いこー♪ラスカール!

花は素晴らしい、行けば必ず撮れるもん。
それよりデジイチを持っている人が沢山いるから浮かないのがいい。
ところで 17mm パンケーキとプロレンズの差を今更ながら痛感する。
去年まではボケの奇麗さなんて気にしなかったのに困った。

GTK4: Image

GtkImage が GTK3 から結構変わっていた。
そもそものインプリメント関数がまるっきり違うし。

pixbuf や surface プロパティが無くなった。
surface にいたっては new_*** すら削除されている、変換しろってことですね。
pixbuf は筆者が使っているぞ、 new_*** が残っていて良かった。
そんなことよりコレですよ。

#!/usr/bin/env python3

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

class RadioWin(Gtk.ApplicationWindow):
    '''
        GTK4: GtkPicture
    '''
    def __init__(self, a):
        Gtk.ApplicationWindow.__init__(self, application=a, title='GTK4')
        image = Gtk.Image(file='400x300px.jpg')
        self.set_child(image)
        #image.set_pixel_size(400)

def app_activate(a):
    w = RadioWin(a)
    w.present()

app = Gtk.Application()
app.connect('activate', app_activate)
app.run()

GTK4.

#!/usr/bin/env python3

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

class Win(Gtk.ApplicationWindow):
    '''
        GTK3: GtkPicture
    '''
    def __init__(self, a):
        Gtk.ApplicationWindow.__init__(self, application=a, title='GTK3')
        image = Gtk.Image(file='400x300px.jpg')
        self.add(image)
        self.show_all()

def app_activate(a):
    w = Win(a)
    w.present()

app = Gtk.Application()
app.connect('activate', app_activate)
app.run()

GTK3.

gtkimage

と、GTK3 と違い画像サイズに自動的設定されなくなっています。
コメントアウトを外すとリサイズできますが正方形にしかできません。

gtkimage

GTK3 の仕様だと巨大画像を間違って読み込むと本当にそのサイズになっていたし。
この Widget はアイコン用途にしか使っては駄目ですよってことなんでしょう。
どうしても GTK3 の時と同じでないと困る場合は GtkPicture を使います。

#!/usr/bin/env python3

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

class RadioWin(Gtk.ApplicationWindow):
    '''
        GTK4: GtkPicture
    '''
    def __init__(self, a):
        Gtk.ApplicationWindow.__init__(self, application=a, title='GTK4')
        gfile = Gio.file_new_for_path('400x300px.jpg')
        pic = Gtk.Picture(file=gfile)
        self.set_child(pic)

def app_activate(a):
    w = RadioWin(a)
    w.present()

app = Gtk.Application()
app.connect('activate', app_activate)
app.run()

いや。
画像を表示したいなら素直に GtkDrawingArea にしましょうね。

ということで今日の GTK4 おしまい。
やっと、やっと夏鳥が撮影できました!

musikui

センダイムシクイ、のようです。
葉っぱ邪魔、見つかりづらいからココにいるんだと解っているけど。

ooruri

オオルリのメス、だと思う。
ほんとヒタギ類のメスって判別がむつかしい。

ooruri

オオルリのオス、これは誰でも間違えない。
キビタキもいたらしいけど筆者の前には現われなかった。

以上、ゴールデンウイーク完全オケラはギリギリ防げた。
おかげで GTK4 の勉強が捗ったのでなんともいえないけど。