[Gtk.Template]Gtk.ColumnViewの使用について Templateを使用してGtk.ColumnViewを表示する。

XMLデータにより定義したGtk.ColumnViewの使用

 Gtk.ColumnViewは、表形式で表示した一覧を表示するためのWidgetであり、使用するには作成の他にもmodelの指定や列の情報の設定などをする必要のあります。これらの設定は、XMLデータでおこなることも可能です。

 今回は、XMLデータでGtk.ColumnViewを作成する方法について紹介します。

今回紹介する内容:
 ・ XMLデータでGtk.ColumnViewのmodelと列情報を指定する
 ・ Gtk.ColumnViewのデータの表示関係を指定する(Gtk.Factgoryの関数定義)
 ・ Gtk.ColumnViewに表示するデータを追加する

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

XMLデータでGtk.ColumnViewのmodelと列情報を指定する

 Gtk.ColumnViewの中には、Gtk.ColumnViewに表示するデータであるmodelと各列の情報を入れるGtk.ColumnViewColumnの内容を記入します。modelの内容は、property name=”model”の中に記入し、Gtk.ColumnViewColumnはGtk.ColumnViewのchildとして記入します。Gtk.ColumnViewColumnは、表示する列の数だけ定義します。

      <object class="GtkColumnView">
        <property name="margin-bottom">20</property>
        <property name="margin-end">20</property>
        <property name="margin-start">20</property>
        <property name="margin-top">20</property>
        <property name="model">
          <object class="GtkNoSelection">
             # 省略
          </object>
        </property>
        <child>
          <object class="GtkColumnViewColumn">
             # 省略
          </object>
        </child>

modelについての指定

 Gtk.ColumnViewのmodelにはGtk.SelectionModelを入れます。Gtk.SelectionModelには、Gtk.NoSelection、Gtk.SingleSelection、Gtk.MultiSelectionがありますが、今回は項目の選択をおこなわないので、Gtk.NoSelectionを指定しています。

 そして、Gtk.NoSelectionのmodelに、Gio.ListStoreを、idにmodelを指定しています。こうすることで、Python側でデータの追加がおこなえるようにしています。

        <property name="model">
          <object class="GtkNoSelection">
            <property name="model">
              <object class="GListStore" id="model"/>
            </property>
          </object>
        </property>

列情報についての指定

 Gtk.ColumnViewColumnは、追加する列を左から順番にGtk.ColumnViewのChildに記入します。Gtk.ColumnViewColumnには、列に追加するデータを表示する部分を定義するFactoryや列のタイトルを定義します。

 また、FactoryにはGtkSignalListItemFactory を指定して、リスト項目を管理するためのシグナルを発行するようにして、シグナル’setup’と’bind’に対して関数との紐付けをおこないます。

        <child>
          <object class="GtkColumnViewColumn">
            <property name="expand">True</property>
            <property name="factory">
              <object class="GtkSignalListItemFactory" id="factory1">
                <signal name="setup" handler="on_list_item_setup"/>
                <signal name="bind" handler="on_list_item_bind1"/>
              </object>
            </property>
            <property name="resizable">True</property>
            <property name="title">番号</property>
          </object>
        </child>

Gtk.ColumnViewのデータの表示関係を指定する(Gtk.Factgoryの関数定義)

 Factoryの定義において、シグナル’setup’と’bind’に紐付けをおこなった関数には、以下のようにおこないます。

 シグナル’setup’の関数には、行で使用されるウィジェット(Gtk.Inscription)を構築し、それらを item に追加する作業を記入します。また、シグナル’bind’の関数には、’setup’で追加したWidgetのテキストにitemより取得した値を記入する作業を記入します。

    @Gtk.Template.Callback()
    def on_list_item_setup(self, factory, item):
        label = Gtk.Inscription()
        item.set_child(label)

    @Gtk.Template.Callback()
    def on_list_item_bind1(self, factory, item):
        item.get_child().set_text(str(item.get_item().num))

Gtk.ColumnViewに表示するデータを追加する

 Gtk.ColumnViewに表示するデータは、そのクラスを作成して、作成したクラスを使用して以下のようにmodel(Gio.ListStore)に入力します。

class Row(GObject.Object):

    def __init__(self, num, group, data):
        super().__init__()
        self.num = num
        self.group = group
        self.data = data
    self.model.append(Row(1, 'グループ1', 'データ1'))
    self.model.append(Row(2, 'グループ1', 'データ2'))
    self.model.append(Row(3, 'グループ1', 'データ3'))
    self.model.append(Row(4, 'グループ2', 'データ1'))
    self.model.append(Row(5, 'グループ2', 'データ2'))
    self.model.append(Row(6, 'グループ3', 'データ1'))
    self.model.append(Row(7, 'グループ3', 'データ2'))

サンプルプログラム

 以下のサンプルプログラムを実行すると、下図のようなデータが入ったGtk.ColumnViewを表示します。

 ※ GtkNoSelectionを指定している為、Gtk.ColumnViewに表示しているデータは選択できません。

<?xml version='1.0' encoding='UTF-8'?>
<!-- Created with Cambalache 0.17.0 -->
<interface>
  <!-- interface-name rgawerg.ui -->
  <requires lib="gtk" version="4.10"/>
  <requires lib="gio" version="2.44"/>
  <template class="window" parent="GtkApplicationWindow">
    <property name="default-height">500</property>
    <property name="default-width">600</property>
    <property name="title">Template ColumnView Test</property>
    <child>
      <object class="GtkColumnView">
        <property name="margin-bottom">20</property>
        <property name="margin-end">20</property>
        <property name="margin-start">20</property>
        <property name="margin-top">20</property>
        <property name="model">
          <object class="GtkNoSelection">
            <property name="model">
              <object class="GListStore" id="model"/>
            </property>
          </object>
        </property>
        <child>
          <object class="GtkColumnViewColumn">
            <property name="expand">True</property>
            <property name="factory">
              <object class="GtkSignalListItemFactory" id="factory1">
                <signal name="setup" handler="on_list_item_setup"/>
                <signal name="bind" handler="on_list_item_bind1"/>
              </object>
            </property>
            <property name="resizable">True</property>
            <property name="title">番号</property>
          </object>
        </child>
        <child>
          <object class="GtkColumnViewColumn">
            <property name="expand">True</property>
            <property name="factory">
              <object class="GtkSignalListItemFactory" id="factory2">
                <signal name="bind" handler="on_list_item_bind2"/>
                <signal name="setup" handler="on_list_item_setup"/>
              </object>
            </property>
            <property name="resizable">True</property>
            <property name="title">項目1</property>
          </object>
        </child>
        <child>
          <object class="GtkColumnViewColumn">
            <property name="expand">True</property>
            <property name="factory">
              <object class="GtkSignalListItemFactory" id="factory3">
                <signal name="bind" handler="on_list_item_bind3"/>
                <signal name="setup" handler="on_list_item_setup"/>
              </object>
            </property>
            <property name="resizable">True</property>
            <property name="title">項目2</property>
          </object>
        </child>
      </object>
    </child>
  </template>
</interface>
# -*- coding: utf-8 -*-

import gi
import os
import logging
gi.require_version('Gtk', '4.0')
from gi.repository import Gtk, Gio, GObject  # noqa E402


logging.basicConfig(
    level=logging.DEBUG, format='[%(levelname)s]: %(message)s')

logging.disable(logging.CRITICAL)

APPID = 'com.github.taniyoshima.g4_fblogt_columnview'


class Row(GObject.Object):

    def __init__(self, num, group, data):
        super().__init__()
        self.num = num
        self.group = group
        self.data = data


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

    model = Gtk.Template.Child()
    factory1 = Gtk.Template.Child()
    factory2 = Gtk.Template.Child()
    factory3 = Gtk.Template.Child()

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

        self.model.append(Row(1, 'グループ1', 'データ1'))
        self.model.append(Row(2, 'グループ1', 'データ2'))
        self.model.append(Row(3, 'グループ1', 'データ3'))
        self.model.append(Row(4, 'グループ2', 'データ1'))
        self.model.append(Row(5, 'グループ2', 'データ2'))
        self.model.append(Row(6, 'グループ3', 'データ1'))
        self.model.append(Row(7, 'グループ3', 'データ2'))

    @Gtk.Template.Callback()
    def on_list_item_setup(self, factory, item):
        label = Gtk.Inscription()
        item.set_child(label)

    @Gtk.Template.Callback()
    def on_list_item_bind1(self, factory, item):
        item.get_child().set_text(str(item.get_item().num))

    @Gtk.Template.Callback()
    def on_list_item_bind2(self, factory, item):
        item.get_child().set_text(item.get_item().group)

    @Gtk.Template.Callback()
    def on_list_item_bind3(self, factory, item):
        item.get_child().set_text(item.get_item().data)


class Gtk4TestApp(Gtk.Application):

    def __init__(self):
        Gtk.Application.__init__(self, application_id=APPID)

    def do_startup(self):
        Gtk.Application.do_startup(self)

    def do_activate(self):
        window = Gtk4TestTest(self)
        window.present()


def main():
    app = Gtk4TestApp()
    app.run()


if __name__ == '__main__':
    main()
タイトルとURLをコピーしました