[Gtk.Template]Gtk.TreeViewの使用② Gtk.Cellrendertoggleの設定

XMLデータにより定義したGtk.Cellrendertoggleの設定

 Gtk.TreeViewにトグルボタンやラジオボタンを追加するのには、Gtk.Cellrendertoggleを使用しますこれらもXMLデータで作成することが可能です。

 今回は、XMLデータでGtk.TreeViewにトグルボタンやラジオボタンを追加する方法を紹介します。

今回紹介する内容
 ・ XMLデータで、Gtk.TreeView内にトグルボタンを作成する
 ・ XMLデータで、Gtk.TreeView内にラジオボタンを作成する

その他の[Gtk.Template]Gtk.TreeViewの記事

代替Widgetの説明記事

XMLデータでのGtk.Cellrendertoggleの記入

XMLデータで、Gtk.TreeView内にトグルボタンを作成する

 XMLデータでのGtk.TreeViewへのトグルボタンの追加は、以下のように記入します。
 1. Gtk.TreeViewColumnに、その列のidやタイトルを指定します。
 2. Gtk.TreeViewColumnの子としてGtk.CellRenderToggleを追加して、それにidと
  トグルイベントが発生した場合に実行する関数を指定します。
 3. <attributes></attributes>内に、Onの状態の項目を指定します。

                <child>
                    <object class="GtkTreeViewColumn" id="gtviewcolumn2">
                        <property name="title">Toggle</property>
                        <child>
                            <object class="GtkCellRendererToggle" id="cellrendertoggle1">
                                <signal name="toggled" handler="on_cell_toggled"/>
                            </object>
                            <attributes>
                                <attribute name="active">1</attribute>
                            </attributes>
                        </child>
                    </object>
                </child>

 トグルボタンのOn/Offが切り替わった場合の処理は、以下の部分でおこないます。

    @Gtk.Template.Callback()
    def on_cell_toggled(self, widget, path):
        self.data[path][1] = not self.data[path][1]

XMLデータで、Gtk.TreeView内にラジオボタンを作成する

 XMLデータでのGtk.TreeViewへのトグルボタンの追加は、以下のように記入します。
 1. Gtk.TreeViewColumnに、その列のidやタイトルを指定します。
 2. Gtk.TreeViewColumnの子としてGtk.CellRenderToggleを追加して、それに①idと
  ②プロパティradioの指定(True:ラジオボタン)と③トグルイベントが発生した場合に
  実行する関数を指定します。
 3. <attributes></attributes>内に、Onの状態の項目を指定します。

                <child>
                    <object class="GtkTreeViewColumn" id="gtviewcolumn3">
                        <property name="title">Radio</property>
                        <child>
                            <object class="GtkCellRendererToggle" id="cellrendertoggle2">
                                <property name="radio">True</property>
                                <signal name="toggled" handler="on_cell_radio_toggled"/>
                            </object>
                            <attributes>
                                <attribute name="active">2</attribute>
                            </attributes>
                        </child>
                    </object>
                </child>

 ラジオボタンの選択がが変更された場合の処理は、以下のようにGtk.TreeViewの各行のラジオボタンに対して、選択したラジオボタンと一致しているかの判定結果を入力することでおこないます。

    @Gtk.Template.Callback()
    def on_cell_radio_toggled(self, widget, path):
    # pathよりselected_path(Gtk.TreePath)を作成する。
        selected_path = Gtk.TreePath(path)
    # Gtk.ListStoreを1行ずつ取得(Gtk.TreeModelRow)して、それからrow.pathにより
    # 行データ(Gtk.TreePath)を取得して、その行データがSelected_pathと一致する
    # かを判定して、その結果をrow[2](判定した行のラジオボタン)に入力する。
        for row in self.data:
            row[2] = row.path == selected_path

サンプルプログラム

 以下のサンプルプログラムを実行すると図のようなトグルボタン(2列目)とラジオボタン(3列目)を持つGtk.TreeViewが表示されます。

実行方法

 下の2つのファイルを同じフォルダに保存して、そのフォルダで以下のコマンドを実行します。

python main.py
<?xml version="1.0" encoding="UTF-8"?>
<interface>
    <template class="window" parent="GtkWindow">
        <property name="default_width">500</property>
        <property name="default_height">250</property>
        <property name="title">Template Gtk.CellRenderText Test</property>
        <child>
            <object class="GtkTreeView" id="treeview">
                <child>
                    <object class="GtkTreeViewColumn" id="gtviewcolumn1">
                        <property name="title">Text</property>
                        <child>
                            <object class="GtkCellRendererText" id="cellrendertext"/>
                            <attributes>
                                <attribute name="text">0</attribute>
                            </attributes>
                        </child>
                    </object>
                </child>
                <child>
                    <object class="GtkTreeViewColumn" id="gtviewcolumn2">
                        <property name="title">Toggle</property>
                        <child>
                            <object class="GtkCellRendererToggle" id="cellrendertoggle1">
                                <signal name="toggled" handler="on_cell_toggled"/>
                            </object>
                            <attributes>
                                <attribute name="active">1</attribute>
                            </attributes>
                        </child>
                    </object>
                </child>
                <child>
                    <object class="GtkTreeViewColumn" id="gtviewcolumn3">
                        <property name="title">Radio</property>
                        <child>
                            <object class="GtkCellRendererToggle" id="cellrendertoggle2">
                                <property name="radio">True</property>
                                <signal name="toggled" handler="on_cell_radio_toggled"/>
                            </object>
                            <attributes>
                                <attribute name="active">2</attribute>
                            </attributes>
                        </child>
                    </object>
                </child>
            </object>
        </child>
    </template>
</interface>
import os
import gi
gi.require_version('Gtk', '4.0')
from gi.repository import Gtk


APPID = 'com.github.taniyoshima.g4_fblogt_cellrendertoggle'


@Gtk.Template(filename=os.path.dirname(__file__) + '/ui_file.ui')
class Gtk4TestTest(Gtk.Window):
    __gtype_name__ = "window"

    treeview = Gtk.Template.Child()

    def __init__(self, app):
        Gtk.Window.__init__(
            self, application=app)

        self.data = Gtk.ListStore(str, bool, bool)
        self.data.append(["Data1", False, True])
        self.data.append(["Data2", True, False])
        self.data.append(["Data3", False, False])

        self.treeview.set_model(self.data)

    @Gtk.Template.Callback()
    def on_cell_toggled(self, widget, path):
        self.data[path][1] = not self.data[path][1]

    @Gtk.Template.Callback()
    def on_cell_radio_toggled(self, widget, path):
        selected_path = Gtk.TreePath(path)
        for row in self.data:
            row[2] = row.path == selected_path


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