GTK4 Python 001

そろそろ GTK4 を使ってみることにする。
筆者はもちろん Gir で PyGObject です。

The GTK Project – A free and open-source cross-platform widget toolkit

GTK 公式サイトに基本サンプルコードがある。
c js py vala は解るけど pl や rs なんて誰が使うんだろう?

GTK 4 Reference Manual: GTK 4 Reference Manual

ドキュメントは現状 Web で見る必要があり。
gtk4-devel-docs を dnf で探したけど見つからない。

Widget Gallery: GTK 4 Reference Manual

廃止されたのはツールバーくらいか。
ツリービューは無くなると思ったけど残したようで。
GtkVideo とか GtkPicture とか、まあいいんじゃない。

Stop using GtkWidget::draw

変更点でコレが一番気になる、まさか draw シグナルを無くすとは。
gtk_main が無くなったのは嬉しい、今でもコレ書くジジイは皆殺しだ。

説明を見ているだけじゃよくワカラン。
とっとと筆者がよく使うサンプルコードで確認。

#!/usr/bin/env python3

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

class TestWindow(Gtk.ApplicationWindow):
    def __init__(self, app):
        Gtk.ApplicationWindow.__init__(self, application=app)
        ''' widget '''
        btn = Gtk.Button(label='SUZUKI')
        btn.connect('clicked', self.on_button_clicked)
        self.label = Gtk.Label(label='Motor Cycle')
        ''' pack '''
        box = Gtk.Box(orientation=Gtk.Orientation.VERTICAL)
        #box.pack_start(btn, False, False, 0) # v3
        box.append(btn)
        box.append(self.label)
        #
        #self.add(box) # v3
        self.set_child(box)
        #self.show_all() # v3
        self.present()

    def on_button_clicked(self, widget):
        self.label.set_text('かっこいい!' * 5)

class TestApplication(Gtk.Application):
    def __init__(self):
        Gtk.Application.__init__(self, application_id='org.suzuki.katana')

    def do_activate(self):
        TestWindow(self)

app = TestApplication()
app.run()

gtk4_1

GtkBox はパッキング情報をコンテナ側に指定ではなくなった。
引き伸ばすか等の情報は挿入する Widget 側のプロパティで指定する。

hexpand|vexpand はデフォルトで FALSE。
これは hexpand-set|vexpand-set を TRUE にしないと変更できない。
halign|valign はデフォルトで GTK_ARIGN_FILL。
margin-* はデフォルトで全部ゼロ、以上で調節する。

gtk_widget_add は GtkWidget の関数だったけど無くなった。
gtk_window_get_child と GtkWindow の関数になった。
普通に UI を作っている人は名前が変わっただけに見えるね。

present は show_all の代わりではない。
GtkWidget のプロパティ visible のデフォルトが TRUE になった。
ただし present しないとウインドウは表示されない。
でこうなったみたい、今までの非表示がデフォルトって変だったもん。

clicked 等のシグナルは変わっていない。
draw が気になるので早々に試してみる。

#!/usr/bin/env python3

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

class TestWindow(Gtk.ApplicationWindow):
    def __init__(self, app):
        Gtk.ApplicationWindow.__init__(self, application=app)
        da = Gtk.DrawingArea()
        da.set_draw_func(self.da_draw_func)
        self.set_child(da)
        #self.resize(400, 150) # v3
        self.set_default_size(400, 150)
        self.present()

    def da_draw_func(self, da, cr, width, height):
        cr.set_source_rgb(0.5, 0.5, 0.5)
        cr.set_line_width(5.0)
        cr.move_to(0, 0)
        cr.line_to(width, height)
        cr.stroke()

class TestApplication(Gtk.Application):
    def __init__(self):
        Gtk.Application.__init__(self, application_id='org.suzuki.hayabusa')

    def do_activate(self):
        TestWindow(self)

app = TestApplication()
app.run()

gtk4_2

なんだシグナルではなく関数登録になっただけで同様に使えるヤン。
全 Widget で draw シグナルが使えるのを変えたかったのかな。
GtkSnapshot がどうとか書いているけど今はよく解っていない。

ついでに、set_size_request は適さないのでコッチ使えだそうです。
いや gtk_window_resize って関数があったやろと少し思うけど。

それより、困ったぞ。
Gedit でスクリプトを debug – Paepoi
コレをやると例外になった時に勝手に死んでくれなくなっている。
端末から ps ax で探して kill するしかなくなる。
でも端末から起動なら Gjs 同様に Ctrl+C が使えるようになった。
けどやはり不便だ、別の手段を考えなければ。