Paepoi

Paepoi » PyGObject Tips » Gtk(PyGObject) Tips | コンボボックス

Gtk(PyGObject) Tips | コンボボックス

# 最終更新日 2019.08.18

2019 年現在の仕様に追記と書き換え。

GtkComboBox
GtkComboBox は GtkTreeModel をデータとして利用するツリービュー同様の Widget です。
クリックするとドロップダウンリストボックスを表示しユーザーに選択を促します。
選択すると changed シグナルが発生します。

GtkCellRenderer を使って表示を行いますが GtkTreeViewColumn は必要ありません。
GtkCellLayout は直接 GtkComboBox にインプリメントされています。

pack_start は GtkBox ではなく GtkCellLayout の関数なので注意。
add_attribute は pack 後でないと適用されないのも注意。
#!/usr/bin/env python3

import sys, gi
gi.require_version('Gtk', '3.0')
from gi.repository import Gtk

trucks = [
    ['三菱ふそう', 'キャンター'],
    ['いすゞ', 'エルフ'],
    ['日産', 'アトラス'],
    ['トヨタ', 'ダイナ']
]

class Win(Gtk.ApplicationWindow):
    '''
        レンダラを変えれば画像やトグルボタン等も入れることができる
        でも今はどんな Widget でも入れられる GtkPopover 等があるし需要無いかも
    '''
    def __init__(self, app):
        Gtk.ApplicationWindow.__init__(self, application=app, title='Py', resizable=False)
        # GtkListStore を作りデータを入れる
        store = Gtk.ListStore(str, str)
        for truck in trucks:
            store.append(truck)
        # GtkComboBox の model プロパティに先程の store を指定
        combobox = Gtk.ComboBox(model=store)
        combobox.connect('changed', self.on_combo_changed)
        # 文字列を表示させるためのレンダラを指定
        renderer = Gtk.CellRendererText()
        combobox.pack_start(renderer, True)
        combobox.add_attribute(renderer, 'text', 0)
        # 説明用ラベル
        label = Gtk.Label(label='大好きな 2t トラックを選んでください')
        # pack
        vbox = Gtk.Box(orientation=Gtk.Orientation.VERTICAL)
        vbox.pack_start(label, False, False, 0)
        vbox.pack_start(combobox, False, False, 0)
        # self
        self.add(vbox)
        self.show_all()

    def on_combo_changed(self, widget):
        '''
            選択するとタイトルバーに書き出す
        '''
        model = widget.get_model()
        active = widget.get_active()
        self.props.title = model[active][1]

class App(Gtk.Application):
    def __init__(self):
        Gtk.Application.__init__(self)

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

    def do_activate(self):
        self.props.active_window.present()

app = App()
app.run(sys.argv)
widget/gtkcombobox1.png
GtkComboBoxText
GtkComboBoxText は GtkComboBox のサブクラスですがシンプルバージョンです。
文字列リストに特化しており GtkTreeModel や GtkCellRenderer の処理が不要になっています。

基本的に append_text で文字列を入れるだけで利用できます。
文字列取得は get_active_text を使います。
#!/usr/bin/env python3

import sys, gi
gi.require_version('Gtk', '3.0')
from gi.repository import Gtk

class Win(Gtk.ApplicationWindow):
    '''
        文字列の一次元配列でいいなら圧倒的に簡単
    '''
    def __init__(self, app):
        Gtk.ApplicationWindow.__init__(self, application=app, title='Py', resizable=False)
        # GtkComboBoxText
        combobox = Gtk.ComboBoxText()
        for s in ['フォワード', 'ファイター', 'タイタン', 'レンジャー']:
            combobox.append_text(s)
        combobox.connect('changed', self.on_combo_changed)
        # 説明用ラベル
        label = Gtk.Label(label='大好きな 4t トラックを選んでください')
        # pack
        vbox = Gtk.Box(orientation=Gtk.Orientation.VERTICAL)
        vbox.pack_start(label, False, False, 0)
        vbox.pack_start(combobox, False, False, 0)
        # self
        self.add(vbox)
        self.show_all()

    def on_combo_changed(self, widget):
        '''
            サブクラスなので実は GtkTreeModel が隠蔽されていることの証明
        '''
        model = widget.get_model()
        active = widget.get_active()
        self.props.title = model[active][0]

class App(Gtk.Application):
    def __init__(self):
        Gtk.Application.__init__(self)

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

    def do_activate(self):
        self.props.active_window.present()

app = App()
app.run(sys.argv)
widget/gtkcombobox2.png
Copyright(C) sasakima-nao All rights reserved 2002 --- 2020.