[Python,Gtk4] Gtk.ScrolledWindowの使用について

Gtk.ScrolledWindowの使用

 Windowの限られた範囲にそれより大きなWidgetを表示する場合、そのWidgetにスクロールバーを付けて、そのWidgetの一部を表示することがあります。この機能をGtk4で実現するものの1つがGtk.ScrolledWindowです。

 今回は、Gtk.ScrolledWindowにWidget(Gtk.TrerView)を載せる方法とスクロールバーの表示を変更する方法について紹介します。

今回紹介する内容
 ・ Gtk.ScrolledWindowを作成する
 ・ Gtk.ScrolledWindowに子Widgetを載せる
 ・ Gtk.ScrolledWindowのスクロールバーの表示方法を指定する

Gtk.ScrolledWindowの作成

Gtk.ScrolledWindowを作成する

 Gtk.ScrolledWindowは、以下のようにGtk.ScrolledWindow()の中にプロパティを記入して作成します。

        scrallwindow = Gtk.ScrolledWindow(
            has_frame=True,
            vexpand=True,
            hexpand=True,
            vscrollbar_policy=Gtk.PolicyType.ALWAYS,
        )

Gtk.ScrolledWindowに載せることができるWidget

 Gtk.ScrolledWindowは、それに載せた子Widgetをスクロール可能にするコンテナです。スクロールは、スクロールバーや外部に関連付けられた調整で行えます。また、子Widgetの周囲にフレームを描画されることも可能です。

 Gtk.Scrollableインターフェースを実装するWidgetはGtk.ScrolledWindowに直接追加でき、実装しないものは、Gtk.Viewportクラスをアダプターとして使用します。

 Gtk.Scrollableインターフェースを実装するWidget:
  Gtk.ColumnView、Gtk.IconView、Gtk.ListBase、Gtk.TextView、Gtk.TreeView、Gtk.Viewprot

参照:https://lazka.github.io/pgi-docs/#Gtk-4.0/classes/ScrolledWindow.html#class-details

Gtk.ScrolledWindowに子Widgetを載せる

 Gtk.ScrolledWindowに子Widgetを載せる作業は、Gtk.ScrolledWindowのメソッドset_child()に子Widgetを指定することでおこないます。

        scrallwindow = Gtk.ScrolledWindow(
     …省略…
        )

        treeview = Gtk.TreeView(model=self.liststore, vexpand=True)

        scrallwindow.set_child(treeview)

Gtk.ScrolledWindowのスクロールバーの表示方法を指定する

 Gtk.ScrolledWindowのスクロールバーの表示方法は、垂直方向がプロパティvscrollbar_policy、水平方向がプロパティhscrollbar_policyで指定します。それらの値は、Gtk.PolicyTypleから選択します。

表示
ALWAYSスクロールバーは常に表示される        
AUTOMATIC  スクロールバーは必要に応じて表示される
NEVERスクロールバーは表示しない。
コンテンツ(子Widget)によりサイズが決まる。
EXTERNALスクロールバーは表示しない。
コンテンツによってサイズを決めない。
詳細はGtk.PolicyTyple参照
Gtk.PolicyTypeの値
        scrallwindow = Gtk.ScrolledWindow(
            has_frame=True,
            vexpand=True,
            hexpand=True,
            vscrollbar_policy=Gtk.PolicyType.ALWAYS,
        )

サンプルプログラム

 以下のサンプルプログラムを実行すると、左図のような画面が表示されます。画面の「追加」ボタンをクリックする度にGtk.TreeViewにデータ[4, ‘Data4’, ‘Number 4’]が追加されます。
 データがGtk.TreeViewから表示がはみ出るまで追加されると、右図のようにスクロールバーが表示されます。

Gtk.ScrolledWIndowにGtk.TreeViewを載せたもの。Gtk.PolicyTypeは、AUTIMATIC
Gtk.ScrolledWIndowにGtk.TreeViewを載せたもの。スクロールバー表示中。Gtk.PolicyTypeは、AUTIMATIC
import gi
gi.require_version('Gtk', '4.0')
from gi.repository import Gtk


APPID = 'com.github.taniyoshima.g4_fblog_treeview'


data = [
    (1, 'Data 1', 'Number 1'),
    (2, 'Data 2', 'Number 2'),
    (3, 'Data 3', 'Number 3'),
]


class Gtk4TestTest(Gtk.Window):

    def __init__(self, app):
        Gtk.Window.__init__(
            self, application=app, title='Gtk.TreeView Test',
            default_width=300, default_height=300
        )

        box = Gtk.Box(
            orientation=Gtk.Orientation.VERTICAL, spacing=20,
            margin_top=20, margin_bottom=20,
            margin_start=20, margin_end=20
        )

        self.liststore = Gtk.ListStore(int, str, str)
        for data_ref in data:
            self.liststore.append(list(data_ref))

        scrallwindow = Gtk.ScrolledWindow(
            has_frame=True,
            vexpand=True,
            hexpand=True,
            vscrollbar_policy=Gtk.PolicyType.ALWAYS,
        )

        treeview = Gtk.TreeView(model=self.liststore, vexpand=True)
        for i, column_title in enumerate(['No', 'Data', 'Number']):
            renderer = Gtk.CellRendererText()
            column = Gtk.TreeViewColumn(column_title, renderer, text=i)
            treeview.append_column(column)

        scrallwindow.set_child(treeview)

        button = Gtk.Button(label="追加")
        button.connect('clicked', self.on_button_clicked)
 
        box.append(scrallwindow)
        box.append(button)
        self.set_child(box)

    def on_button_clicked(self, button):
        self.liststore.append([4, 'Data 4', 'Number 4'])


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