Paepoi » GTK4(Python) Tips » GTK4(Python) Tips | GtkApplicationWindow
GTK4(Python) Tips | GtkApplicationWindow
# 最終更新日 2023.05.14
application プロパティは GtkWindow 側にありますがコチラを使えということみたいです。
GTK4 では GtkWindow 自体は継承して使う Interface として提供されている感じです。
ウインドウ側にて close-request シグナルで破棄を行う処理も必要もありません。
閉じるボタンを押す(close-request 発生)で GtkApplication と切り離され自動的に破棄されます。
GTK3 までとの最大の違いはすべての Widget がデフォルトで「表示」に変更されたことです。
関数も GTK3 の時といくつか変わっているので以下に基本的サンプルを。
Adw については別ページにて。

親コンテナ側で指定していたパッキング情報は子 Widget のプロパティに移管されています。
ウインドウサイズを変更しないアプリなら単純になったとも言えます。

ただしそれだけではなく CSS にて透過させる処理が必要になりました。
デスクトップマスコット等の背景透過画像を表示させるには以下のようにします。

ApplicationWindow
ウインドウは GtkApplicationWindow という GtkWindow のサブクラスを使います。application プロパティは GtkWindow 側にありますがコチラを使えということみたいです。
GTK4 では GtkWindow 自体は継承して使う Interface として提供されている感じです。
ウインドウ側にて close-request シグナルで破棄を行う処理も必要もありません。
閉じるボタンを押す(close-request 発生)で GtkApplication と切り離され自動的に破棄されます。
GTK3 までとの最大の違いはすべての Widget がデフォルトで「表示」に変更されたことです。
関数も GTK3 の時といくつか変わっているので以下に基本的サンプルを。
Adw については別ページにて。
#!/usr/bin/env python3 import gi gi.require_version('Gtk', '4.0') gi.require_version('Adw', '1') from gi.repository import Gtk, Adw class Win(Gtk.ApplicationWindow): ''' GTK4 でウインドウを作るサンプル ''' def __init__(self, a): # ダークテーマを OS の設定に追従させる manager = Adw.StyleManager.get_default() manager.set_color_scheme(Adw.ColorScheme.DEFAULT) # 初期化 Gtk.ApplicationWindow.__init__(self, title='Title', application=a) button = Gtk.Button(label='ハローワールド', halign=Gtk.Align.CENTER) button.connect('clicked', self.on_button_connect) # add は set_child に変わりました self.set_child(button) # resize は set_default_size に変わりました self.set_default_size(200, -1) # # widget はデフォルトで表示になったので show_all は不要 # delete-event は close-request に変わりましたが処理不要です def on_button_connect(self, button): ''' ボタンを押す毎にハローワールドが増える ''' button.props.label += '\nハローワールド' # GtkApplication 最小コード app = Gtk.Application() app.connect('activate', lambda a: Win(a).present()) app.run()

パッキング
GtkBox を使ったパッキングは GTK4 で完全に変更されました。親コンテナ側で指定していたパッキング情報は子 Widget のプロパティに移管されています。
pack_start(child, expand, fill, padding) # 上記パッキング情報は子 Widget の以下プロパティで指定 expand: hexpand|vexpand fill: halign|valign padding: margin-top|margin-botom|margin-start|margin-end何をどう指定すればどういう動作になるのかは御自身で色々試してみてください。
ウインドウサイズを変更しないアプリなら単純になったとも言えます。
#!/usr/bin/env python3 import gi gi.require_version('Gtk', '4.0') gi.require_version('Adw', '1') from gi.repository import Gtk, Adw class Win(Gtk.ApplicationWindow): ''' 縦: Gtk.Orientation.VERTICAL 横: Gtk.Orientation.HORIZONTAL ''' def __init__(self, a): ''' リサイズするとボタンのほうだけ大きくなるサンプル ''' manager = Adw.StyleManager.get_default() manager.set_color_scheme(Adw.ColorScheme.DEFAULT) Gtk.ApplicationWindow.__init__(self, title='Title', application=a) # 縦型コンテナの作成 vbox = Gtk.Box(orientation=Gtk.Orientation.VERTICAL) # ボタン button = Gtk.Button(label='ボタン', vexpand=True) button.connect('clicked', self.on_button_clicked) # 一行エディットは後で参照するので self にくっつける self.entry = Gtk.Entry(editable=False, text='ボタンを押せ') # pack_start pack_end は append に変わりました vbox.append(button) vbox.append(self.entry) self.set_child(vbox) def on_button_clicked(self, widget): self.entry.set_text('Hello World') app = Gtk.Application() app.connect('activate', lambda a: Win(a).present()) app.run()

枠無しウインドウ
枠無しウインドウは GTK3 同様に decorated プロパティを使います。ただしそれだけではなく CSS にて透過させる処理が必要になりました。
デスクトップマスコット等の背景透過画像を表示させるには以下のようにします。
#!/usr/bin/env python3 import gi, sys gi.require_version('Gtk', '4.0') from gi.repository import Gtk, GdkPixbuf, Gdk # Picture File PNGFILE = 'test.png' class Win(Gtk.ApplicationWindow): ''' GTK4: No Decorated Window ''' def __init__(self, a): Gtk.ApplicationWindow.__init__(self, application=a, decorated=False) # # 定義されていない CSS class をセットすると透過になる # 正しい方法はまだ勉強中なのでコレで許して # print(self.get_css_classes()) #=> background self.set_css_classes(['no_name']) # # Mouse Signal click = Gtk.GestureClick() click.connect('stopped', self.on_gesture_click_stopped) click.connect('released', self.on_gesture_cllick_released) self.add_controller(click) # Draw self.pixbuf = GdkPixbuf.Pixbuf.new_from_file(PNGFILE) da = Gtk.DrawingArea() da.set_draw_func(self.da_draw_func) self.set_child(da) # Resize self.set_default_size(self.pixbuf.get_width(), self.pixbuf.get_height()) def da_draw_func(self, da, cr, width, height): Gdk.cairo_set_source_pixbuf(cr, self.pixbuf, 0, 0) cr.paint() def on_gesture_click_stopped(self, click): ''' マウスでウインドウを移動 ''' button = click.get_button() toplevel = self.get_surface() # GdkToplevel display = self.get_display() seat = display.get_default_seat() device = seat.get_pointer() s, win_x, win_y = device.get_surface_at_position() time = device.get_timestamp() toplevel.begin_move(device, button, win_x, win_y, time) def on_gesture_cllick_released(self, widget, n_press, x, y): ''' ダブルクリックで終了 ''' if n_press == 2: self.close() app = Gtk.Application() app.connect('activate', lambda a: Win(a).present()) app.run()

Copyright(C) sasakima-nao All rights reserved 2002 --- 2025.