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()