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

目的

 Gtk.ComboBoxは、Gtk4.10より非推奨となったWidgetですが、Gtk4では利用し続けることが可能なので、その使い方を見ていきます。代替Widgetは、Gtk.ComboBoxTextと同じGtk.DorpDownです。

 今回は、Gtk.ComboBoxへの①項目の追加、②テキストの入力の設定、③項目の選択処理の方法を見ます。

Gtk.ComboBoxの設定

 Gtk.ComboBoxの外観や動作、項目の操作は、プロパティやメソッドを使用して指定します。

項目を追加する

 Gtk.ComboBoxへの項目の追加は、まず登録する項目データをGtk.ListStoreに入れたものを作成して、それをGtk.ComboBoxに追加します。

# Gtk.ListStoreの作成とデータの追加
        store = Gtk.ListStore(int, str) 
        store.append([1, 'number 1'])

# Gtk.ComboBoxへのGtk.ListStoreの追加
        combo1 = Gtk.ComboBox.new_with_model_and_entry(store)
        combo2 = Gtk.ComboBox.new_with_model(store2)

 Gtk.ListStoreのデータ処理は、メソッドを使用することで追加、削除、移動が行えます。

テキスト入力を可能にする

 Gtk.ComboBoxへのテキスト入力の追加は、メソッドnew_with_entry()もしくはnew_with_model_and_entry()によりGtk.ComboBoxを定義したり、プロパティhas_entryを使用することで行います。

# Gtk.ComboBoxへのエントリーの追加(メソッドnew_with_entry()を使用)
         combo1 = Gtk.ComboBox.new_with_model_and_entry(store)

項目を選択した場合の処理

 Gtk.ComboBoxの項目が選択された場合に、表示している値を取得するには、①combo1のシグナルchangedとon_combo1_changedの紐付けを行い、②on_combo1_change()内でGtk.ComboBoxの値のアクティブなiterを取得を行い、iterが有る場合はmodelより値を指定します。無い場合は、Gtk.ComboBoxのエントリーの値を取得します。

    combo1.connect("changed", self.on_combo1_changed)

    def on_combo1_changed(self, combo):
        iter = combo.get_active_iter()
        if iter is not None:
            model = combo.get_model()
            row_id, name = model[iter][:2]
            print("Combo1 選択: ID=%d, name=%s" % (row_id, name))
        else:
            entry = combo.get_child()
            print("Combo1 入力: %s" % entry.get_text())

iterが有る場合(if iter is not None:)

 Gtk.ComboBoxよりmodelを取得して、modelより選択している項目のidと値を取得します。

iterが無い場合(else:)

 Gtk.ComboBoxよりentry(new_with_entry()を実行することでGtk.ComboBoxに付けている)を取得して、その値をentry.get_text()により取得します。

Gtk.ComboBoxのサンプルプログラム

 以下のサンプルプログラムを実行すると、下図のような2組のGtk.LabelとGtk.ComboBoxが表示されます。①テキスト入力可横のGtk.ComboBox(Combo1)は、選択を変更した場合にターミナルに選択した項目もしくはテキスト入力した文字を表示します。②テキスト入力不可横のGtk.ComboBoxText(Combo2)は選択を変更した場合に、選択した値をターミナルに表示します。

import gi
gi.require_version('Gtk', '4.0')
from gi.repository import Gtk表示している値を取得する


APPID = 'com.github.taniyoshima.'


class Gtk4TestTest(Gtk.Window):

    def __init__(self, app):
        Gtk.Window.__init__(
            self, application=app, title='Gtk.ComboBox Test')

        grid = Gtk.Grid(
            width_request=350, height_request=200,
            margin_top=20, margin_bottom=20,
            margin_start=20, margin_end=20,
            column_spacing=30, row_spacing=30,
            hexpand=True, vexpand=True,
        )

        label1 = Gtk.Label(label='①Combo1:テキスト入力可', xalign=0.0)

        store = Gtk.ListStore(int, str)
        store.append([1, 'number 1'])
        store.append([2, 'number 2'])
        store.append([3, 'number 3'])
        store.append([4, 'number 4'])
        store.append([5, 'number 5'])

        combo1 = Gtk.ComboBox.new_with_model_and_entry(store)
        combo1.connect("changed", self.on_combo1_changed)
        combo1.set_entry_text_column(1)

        label2 = Gtk.Label(label='②Combo2:テキスト入力不可', xalign=0.0)

        store2 = Gtk.ListStore(str)
        num_data = [
            'number 1',
            'number 2',
            'number 3',
            'number 4',
        ]
        for data in num_data:
            store2.append([data])

        combo2 = Gtk.ComboBox.new_with_model(store2)
        combo2.connect("changed", self.on_combo2_changed)
        renderer_text = Gtk.CellRendererText()
        combo2.pack_start(renderer_text, True)
        combo2.add_attribute(renderer_text, "text", 0)

        grid.attach(label1, 0, 0, 1, 1)(Combo2)
        grid.attach(combo1, 1, 0, 1, 1)
        grid.attach(label2, 0, 1, 1, 1)
        grid.attach(combo2, 1, 1, 1, 1)

        self.set_child(grid)

    def on_combo1_changed(self, combo):
        iter = combo.get_active_iter()
        if iter is not None:
            model = combo.get_model()
            row_id, name = model[iter][:2]
            print("Combo1 選択: ID=%d, name=%s" % (row_id, name))
        else:
            entry = combo.get_child()
            print("Combo1 入力: %s" % entry.get_text())

    def on_combo2_changed(self, combo):
        iter = combo.get_active_iter()
        if iter is not None:
            model = combo.get_model()
            country = model[iter][0]
            print("Combo2: %s" % country)


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

まとめ

  • Gtk.ComboBoxへの項目の追加は、以下の手順で行います。
     ①登録する項目データをGtk.ListStoreに入れたものの作成
     ②Gtk.ComboBoxにGtk.ListStoreを追加
  • Gtk.ListStoreのデータ処理は、メソッドを使用することで追加、削除、移動が行えます。
  • Gtk.ComboBoxへのテキスト入力の追加は、以下のいずれかの方法で行います。
    ①メソッドnew_with_entry()もしくはnew_with_model_and_entry()を使用して
     Gtk.ComboBoxを定義
    ②プロパティhas_entryを使用
  • Gtk.ComboBoxの項目が選択された場合に、表示している値を取得するのには以下の作業を行います
     ①combo1のシグナルchangedと関数on_combo1_changedの紐付け 
     ②関数on_combo1_change()内でGtk.ComboBoxの値のアクティブなiterを取得
     ③iterが有る場合は、modelより値を取得
     ④iterが無い場合は、Gtk.ComboBoxのエントリーの値を取得
     (Gtk.ComboBoxにGtk.Entryを付けている場合)

 次回の予定

 次回は、複数行のテキストを表示、編集するGtk.TextViewについて見ます。

タイトルとURLをコピーしました