[Gtk.Template]Gtk.TreeViewの使用③ Gtk.Cellrendercomboの設定

目標

 Gtk.TreeViewの中でコンボボックスを追加するのにはGtk.Cellrendercomboを使用します。このWidgetも、XMLデータ側で指定することが可能です。

 今回は、XMLデータでGtk.TreeViewにコンボボックスを追加する方法について紹介します。

今回紹介する内容
 ・ XMLデータで、Gtk.TreeView内にコンボボックスを作成する
 ・XMLデータで、Gtk.TreeView内に作成したコンボボックスの項目を作成する
 ・XMLデータで、Gtk.TreeViewに表示するデータ(コンボボックスの値を含む)を作成する

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

代替Widgetの説明記事

Gtk.Cellrendercomboの設定

XMLデータで、Gtk.TreeView内にコンボボックスを作成する

 XMLデータでのGtk.TreeViewへのトグルボタンの追加は、以下のように記入します。
 1. Gtk.TreeViewColumnに、その列のidやタイトルを指定します。
 2. Gtk.TreeViewColumnの子としてGtk.CellRendercomboを追加して、それにidとプロパティ
  エディットイベントが発生した場合に実行する関数を指定します。
 3. <attributes></attributes>内で、表示するListStoreの列と形式(name=”text”)を指定します。

                <child>
                    <object class="GtkTreeViewColumn" id="gtviewcolumn2">
                        <property name="title">Toggle</property>
                        <child>
                            <object class="GtkCellRendererCombo" id="cellrenderercombo">
                                <property name="editable">True</property>
                                <property name="model">data1</property>
                                <property name="text-column">0</property>
                                <property name="has-entry">False</property>
                                <signal name="edited" handler="on_combo_changed"/>
                            </object>
                            <attributes>
                                <attribute name="text">1</attribute>
                            </attributes>
                        </child>
                    </object>
                </child>

XMLデータで、Gtk.TreeView内に作成したコンボボックスの項目を作成する

コンボボックスの項目を設定するには、項目をGtk.ListStoreによって作成して、それをGtk.CellRendererCombo側で項目に指定します。

コンボボックス用の項目(Gtk.ListStore)の作成

 コンボボックスの項目はGtk.ListStoreで作成するため、以下のように</template>の後にデータを記入します。
 1. <object class=”GtkListStore” id=”data1″></object>でGtk.ListStoreを作成する。
  ※ idは、Gtk.CellRendererCombo側でこのGtk.ListStoreを指定するのに使用
 2. <columns></columns>内にGtk.ListStoreの列の情報を記入する。
  ※ 今回はgchararray型の1列のみを指定
 3. <data></data>の中に、<row><col>値</col></row>の形で値を記入します。
  ※ colのidは、列番号であり今回は1列のデータなので0(列数 – 1の値)にしています。

    </template>
    <object class="GtkListStore" id="data1">
        <columns>
            <column type="gchararray"/>
        </columns>
        <data>
            <row>
                <col id="0">Number 1</col>
            </row>
            <row>
                <col id="0">Number 2</col>
            </row>
            <row>
                <col id="0">Number 3</col>
            </row>
            <row>
                <col id="0">Number 4</col>
            </row>
        </data>
    </object>  

Gtk.CellRendererCombo側での項目(Gtk.ListStore)の指定

 コンボボックスへの追加は、<object class=”GtkCellRendererCombo” id=”cellrenderercombo”></objcet>内で、<property name=”model”>data1</property>のようにます。

                            <object class="GtkCellRendererCombo" id="cellrenderercombo">
                                … 省略 …
                                <property name="model">data1</property>
                                … 省略 …
                            </object>

XMLデータで、Gtk.TreeViewに表示するデータ(コンボボックスの値を含む)を作成する

 Gtk.TreeViewに表示するデータもGtk.ListStoreで作成するため、</template>の後に以下のように記入します。
 1. <object class=”GtkListStore” id=”data2″></object>でGtk.ListStoreを作成する。
  ※ idは、Gtk.TreeView側でmodelにこのGtk.ListStoreを指定するのに使用
 2. <columns></columns>内にGtk.ListStoreの列の情報を記入する。
  ※ 今回はgchararray型の2列を指定
 3. <data></data>の中に、<row><col>値</col></row>の形で値を記入します。
  ※ 今回は2列あるので、colのid=”0″(1列目の値)とid=”1″(2列目の値)を記入しています。

    <object class="GtkListStore" id="data2">
        <columns>
            <column type="gchararray"/>
            <column type="gchararray"/>
        </columns>
        <data>
            <row>
                <col id="0">Data 1</col>
                <col id="1">Number 1</col>
            </row>
            <row>
                <col id="0">Data 2</col>
                <col id="1">Number 4</col>
            </row>
            <row>
                <col id="0">Data 3</col>
                <col id="1">Number 3</col>
            </row>
        </data>
    </object>

Gtk.TreeViewのmodelに作成したGtk.ListStoreの指定

 Gtk.TreeViewのmodelに作成したGtk.ListStoreを指定するには、<object class=”GtkTreeView” id=”treeview”></object>内で、<property name=”model”>data2</property>のように記入します。

            <object class="GtkTreeView" id="treeview">
                <property name="model">data2</property>
                <child>

サンプルプログラム

 以下のサンプルプログラムを実行すると図のようなテキスト列(1列目)とコンボの列(2列目)をもつGtk.TreeViewが表示されます。コンボの列の項目(Number *)をマウスで左クリックするとコンボが表示されて、それにより項目を選択することができます。

実行方法

 下の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">
                <property name="model">data2</property>
                <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="GtkCellRendererCombo" id="cellrenderercombo">
                                <property name="editable">True</property>
                                <property name="model">data1</property>
                                <property name="text-column">0</property>
                                <property name="has-entry">False</property>
                                <signal name="edited" handler="on_combo_changed"/>
                            </object>
                            <attributes>
                                <attribute name="text">1</attribute>
                            </attributes>
                        </child>
                    </object>
                </child>
            </object>
        </child>
    </template>
    <object class="GtkListStore" id="data1">
        <columns>
            <column type="gchararray"/>
        </columns>
        <data>
            <row>
                <col id="0">Number 1</col>
            </row>
            <row>
                <col id="0">Number 2</col>
            </row>
            <row>
                <col id="0">Number 3</col>
            </row>
            <row>
                <col id="0">Number 4</col>
            </row>
        </data>
    </object>  
    <object class="GtkListStore" id="data2">
        <columns>
            <column type="gchararray"/>
            <column type="gchararray"/>
        </columns>
        <data>
            <row>
                <col id="0">Data 1</col>
                <col id="1">Number 1</col>
            </row>
            <row>
                <col id="0">Data 2</col>
                <col id="1">Number 4</col>
            </row>
            <row>
                <col id="0">Data 3</col>
                <col id="1">Number 3</col>
            </row>
        </data>
    </object>
</interface>
import os
import gi
gi.require_version('Gtk', '4.0')
from gi.repository import Gtk


APPID = 'com.github.taniyoshima.g4_fblogt_cellrendercombo'


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

    data2 = Gtk.Template.Child()

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

    @Gtk.Template.Callback()
    def on_combo_changed(self, widget, path, text):
        self.data2[path][1] = text


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