Paepoi » PyGObject Tips » Gtk(PyGObject) Tips | レンダラ
Gtk(PyGObject) Tips | レンダラ
# 最終更新日 2019.09.01
2019 年現在の仕様に追記と書き換え、PyGtk 互換の削除。
GtkCellRenderer は GtkTreeView, GtkComboBox で使います。
データをどのように表示させるかを指定する Widget です。
直接使うことはありません、派生された以下を利用します。
基本的なものですので一般例はツリービュー、リストビューを見てもらうとしてここでは編集手段を。
editable プロパティを True にして edited シグナルを利用すれば編集可能。
データモデル (GtkTreeStore, GtkListStore) のデータを書き換える必要があります。
そのレンダラを使用したコラムはデータ追加を行ってもすべて書き換え可能になります。
edited ハンドラで PyGObject の場合は以下のようにすれば GtkTreeModel のデータを変更できる。
コメント内に devhelp の正式な手段もいれておきましたので参照ください。
キーボードアクセラレータ関連に特化したウイジェットのようです。
editable プロパティを真にしてレンダラ部をクリックすると accel-edited シグナルが発行される。
このパラメータを利用して GtkAccelMap の変更を行うといったことができます。
GtkTreeModel に入れたデータから選択する GtkComboBox と同様に利用できます。
プロパティの editable を True にして model を指定すればドロップ選択が可能になる。
has-entry が True なら直書きもできる、text-column は指定した model のデータ位置。
又 edited シグナルも利用できるようです。
GtkAdjustment を adjustment プロパティに入れて利用します。
TreeModel で使用するデータは当然 int ですがレンダラは text なので注意しましょう。
専用のシグナルは用意されていません、edited シグナルを利用します。
ストックは非推奨なので代わりに icon-name プロパティを使ってください。
自分で用意した画像を表示する場合は pixbuf プロパティ指定で GdkPixbuf を。
pixbuf-expander-closed, pixbuf-expander-open は is-expand プロパティが真の時に使う。
ツリー表示を開いた閉じたで画像を変更したい場合なんかに利用します。
GDK_TYPE_PIXBUF の GType は以下のように。
Value プロパティに 0...100 の値で何パーセント進んだかを入れて利用します。
昔の Windows では砂時計、今はクルクル回るアレです。
active プロパティで表示し pulse プロパティで回り具合を調節します。
チェックボックスをクリックすると toggled シグナルが発生しますが表示は変わりません。
チェック状態を変更したい場合は以下のように自力で行う必要があります。
2019 年現在の仕様に追記と書き換え、PyGtk 互換の削除。
GtkCellRenderer は GtkTreeView, GtkComboBox で使います。
データをどのように表示させるかを指定する Widget です。
直接使うことはありません、派生された以下を利用します。
レンダラ | 型 | プロパティ |
---|---|---|
GtkCellRendererText | str | text |
+----GtkCellRendererAccel | str | text |
+----GtkCellRendererCombo | str | text |
+----GtkCellRendererSpin | int | text |
GtkCellRendererPixbuf | GdkPixbuf or str | pixbuf or icon-name |
GtkCellRendererProgress | int | value |
GtkCellRendererSpinner | int | text |
GtkCellRendererToggle | bool | active |
GtkCellRendererText
GtkCellRendererText は名前のとおり文字列を表示するレンダラです。基本的なものですので一般例はツリービュー、リストビューを見てもらうとしてここでは編集手段を。
editable プロパティを True にして edited シグナルを利用すれば編集可能。
データモデル (GtkTreeStore, GtkListStore) のデータを書き換える必要があります。
そのレンダラを使用したコラムはデータ追加を行ってもすべて書き換え可能になります。
edited ハンドラで PyGObject の場合は以下のようにすれば GtkTreeModel のデータを変更できる。
コメント内に devhelp の正式な手段もいれておきましたので参照ください。
#!/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') # CellRendererText cell = Gtk.CellRendererText(editable=True) # Column column = Gtk.TreeViewColumn() column.pack_start(cell, True) column.add_attribute(cell, 'text', 0) # ListStore store = Gtk.ListStore.new([str]) store.append(['W クリックで']) store.append(['書き換え可能']) tree = Gtk.TreeView(model=store, headers_visible=False) tree.append_column(column) # Button button = Gtk.Button(label='レンダラの追加') # Signal cell.connect('edited', self.on_cell_edited, store) button.connect('clicked', self.on_button_clicked, store) # pack vbox = Gtk.Box(orientation=Gtk.Orientation.VERTICAL) vbox.pack_start(tree, False, False, 0) vbox.pack_start(button, False, False, 0) self.add(vbox) self.show_all() def on_cell_edited(self, renderer, path, new_text, store): ''' # C Like it = store.get_iter_from_string(path) store.set_value(it, 0, new_text) ''' store[path][0] = new_text def on_button_clicked(self, widget, store): ''' レンダラの追加 ''' store.append(['追加レンダラ']) 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)
GtkCellRendererAccel
GtkCellRendererAccel は GNOME のキーボードショートカット設定等に使われているもの。キーボードアクセラレータ関連に特化したウイジェットのようです。
editable プロパティを真にしてレンダラ部をクリックすると accel-edited シグナルが発行される。
このパラメータを利用して GtkAccelMap の変更を行うといったことができます。
#!/usr/bin/env python3 import sys, gi gi.require_version('Gtk', '3.0') from gi.repository import Gtk, Gio class Win(Gtk.ApplicationWindow): ''' レンダラ ''' def __init__(self, app): Gtk.ApplicationWindow.__init__(self, application=app, title='Py') # Renderer cell_text = Gtk.CellRendererText() cell_accel = Gtk.CellRendererAccel(editable=True) # Signal cell_accel.connect('accel-edited', self.on_accel_edited) # Column column_text = Gtk.TreeViewColumn(title='動作') column_text.pack_start(cell_text, True) column_text.add_attribute(cell_text, 'text', 0) column_accel = Gtk.TreeViewColumn(title='キー') column_accel.pack_start(cell_accel, True) column_accel.add_attribute(cell_accel, 'text', 1) # ListStore self.store = Gtk.ListStore.new([str, str]) self.store.append(['新規ウインドウ', 'Ctrl+N']) self.store.append(['終了', 'Ctrl+Q']) tree = Gtk.TreeView(model=self.store) tree.append_column(column_text) tree.append_column(column_accel) # self.add(tree) self.show_all() def on_accel_edited(self, accel, path_string, accel_key, accel_mods, hardware_keycode): ''' 以下だと '<Primary>q' みたいな文字列になる Primary と Control は同じ意味に扱われる Gtk.accelerator_name(accel_key, accel_mods) ''' self.store[path_string][1] = Gtk.accelerator_get_label(accel_key, accel_mods) # 変更 s = Gtk.accelerator_name(accel_key, accel_mods) if self.store[path_string][0] == '新規ウインドウ': self.props.application.set_accels_for_action('app.new_window_action', [s]) elif self.store[path_string][0] == '終了': self.props.application.set_accels_for_action('app.quit_action', [s]) class App(Gtk.Application): def __init__(self): Gtk.Application.__init__(self) def do_startup(self): Gtk.Application.do_startup(self) # GAction 作成 new_window_action = Gio.SimpleAction(name='new_window_action') quit_action = Gio.SimpleAction(name='quit_action') # 追加 self.add_action(new_window_action) self.add_action(quit_action) # アクセラレーターの指定 self.set_accels_for_action('app.new_window_action', ['<Control>N']) self.set_accels_for_action('app.quit_action', ['<Control>Q']) # シグナル new_window_action.connect('activate', self.on_new_window_action) quit_action.connect('activate', self.on_quit_action) Win(self) def on_new_window_action(self, action, parameter): Win(self) def on_quit_action(self, action, parameter): self.quit() def do_activate(self): self.props.active_window.present() app = App() app.run(sys.argv)
GtkCellRendererCombo
GtkCellRendererCombo はその名のとおりコンボボックスです。GtkTreeModel に入れたデータから選択する GtkComboBox と同様に利用できます。
プロパティの editable を True にして model を指定すればドロップ選択が可能になる。
has-entry が True なら直書きもできる、text-column は指定した model のデータ位置。
又 edited シグナルも利用できるようです。
#!/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') # Data store_items = Gtk.ListStore.new([str]) for item in ['純白', 'シマパン', 'Tバック', 'はいていない']: store_items.append([item]) # Renderer cell_text = Gtk.CellRendererText() cell_combo = Gtk.CellRendererCombo(editable=True, model=store_items, has_entry=False, text_column=0) # Signal cell_combo.connect('changed', self.on_changed, store_items) # Column column_text = Gtk.TreeViewColumn(title='好きな下着') column_text.pack_start(cell_text, True) column_text.add_attribute(cell_text, 'text', 0) column_combo = Gtk.TreeViewColumn(title='選択') column_combo.pack_start(cell_combo, True) column_combo.add_attribute(cell_combo, 'text', 1) # ListStore self.store = Gtk.ListStore.new([str, str]) tree = Gtk.TreeView(model=self.store) tree.append_column(column_text) tree.append_column(column_combo) # Data self.store.append(['JK', '選んでください']) self.store.append(['熟女', '選んでください']) # self.add(tree) self.show_all() def on_changed(self, combo, path_string, new_iter, model): self.store[path_string][1] = model.get_value(new_iter, 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)
GtkCellRendererSpin
GtkCellRendererSpin はその名のとおりスピンボタンです。GtkAdjustment を adjustment プロパティに入れて利用します。
TreeModel で使用するデータは当然 int ですがレンダラは text なので注意しましょう。
専用のシグナルは用意されていません、edited シグナルを利用します。
#!/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') # Renderer cell_text = Gtk.CellRendererText() cell_spin = Gtk.CellRendererSpin(editable=True, adjustment=Gtk.Adjustment.new(0, 50, 2000, 1, 100, 0)) # Signal cell_spin.connect('edited', self.on_cell_edited) # Column column_text = Gtk.TreeViewColumn(title='変な排気量') column_text.pack_start(cell_text, True) column_text.add_attribute(cell_text, 'text', 0) column_spin = Gtk.TreeViewColumn(title='cc') column_spin.pack_start(cell_spin, True) column_spin.add_attribute(cell_spin, 'text', 1) # ListStore self.store = Gtk.ListStore.new([str, int]) tree = Gtk.TreeView(model=self.store) tree.append_column(column_text) tree.append_column(column_spin) # Data self.store.append(['CB500X', 471]) self.store.append(['Street Triple', 675]) # self.add(tree) self.show_all() def on_cell_edited(self, renderer, path, new_text): ''' renderer.props.digits がゼロのままなんだが... ''' self.store[path][1] = int(new_text) 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)
GtkCellRendererPixbuf
GtkCellRendererPixbuf はその名のとおり画像を表示するレンダラです。ストックは非推奨なので代わりに icon-name プロパティを使ってください。
自分で用意した画像を表示する場合は pixbuf プロパティ指定で GdkPixbuf を。
pixbuf-expander-closed, pixbuf-expander-open は is-expand プロパティが真の時に使う。
ツリー表示を開いた閉じたで画像を変更したい場合なんかに利用します。
GDK_TYPE_PIXBUF の GType は以下のように。
#!/usr/bin/env python3 import sys, gi gi.require_version('Gtk', '3.0') from gi.repository import Gtk, GdkPixbuf SQUARE = [ '16 16 2 1', ' c #000000', '. c #FFFFFF', ' ', ' .............. ', ' .............. ', ' .............. ', ' .............. ', ' .............. ', ' .............. ', ' .............. ', ' .............. ', ' .............. ', ' .............. ', ' .............. ', ' .............. ', ' .............. ', ' .............. ', ' '] TRIANGLE = [ '16 16 2 1', ' c #000000', '. c #FFFFFF', ' ...............', ' ..............', ' . .............', ' .. ............', ' ... ...........', ' .... ..........', ' ..... .........', ' ...... ........', ' ....... .......', ' ........ ......', ' ......... .....', ' .......... ....', ' ........... ...', ' ............ ..', ' ............. .', ' '] class Win(Gtk.ApplicationWindow): ''' レンダラ ''' def __init__(self, app): Gtk.ApplicationWindow.__init__(self, application=app, title='Py') # Renderer cell_1 = Gtk.CellRendererPixbuf() cell_2 = Gtk.CellRendererPixbuf() # Column column_1 = Gtk.TreeViewColumn(title='icon') column_1.pack_start(cell_1, True) column_1.add_attribute(cell_1, 'icon-name', 0) column_2 = Gtk.TreeViewColumn(title='pixbuf') column_2.pack_start(cell_2, True) column_2.add_attribute(cell_2, 'pixbuf', 1) # ListStore self.store = Gtk.ListStore.new([str, GdkPixbuf.Pixbuf.__gtype__]) tree = Gtk.TreeView(model=self.store) tree.append_column(column_1) tree.append_column(column_2) # Create Pixbuf pixbuf1 = GdkPixbuf.Pixbuf.new_from_xpm_data(SQUARE) pixbuf2 = GdkPixbuf.Pixbuf.new_from_xpm_data(TRIANGLE) # Data self.store.append(['system-search-symbolic', pixbuf1]) self.store.append(['help-about-symbolic', pixbuf2]) # self.add(tree) self.show_all() 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)
GtkCellRendererProgress
GtkCellRendererProgress はその名のとおりプログレスバーです。Value プロパティに 0...100 の値で何パーセント進んだかを入れて利用します。
#!/usr/bin/env python3 import sys, gi gi.require_version('Gtk', '3.0') from gi.repository import Gtk, GLib class Win(Gtk.ApplicationWindow): ''' レンダラ ''' def __init__(self, app): Gtk.ApplicationWindow.__init__(self, application=app, title='Py') # Renderer cell = Gtk.CellRendererProgress() # Column column = Gtk.TreeViewColumn(title='progress') column.pack_start(cell, True) column.add_attribute(cell, 'value', 0) # ListStore self.store = Gtk.ListStore.new([int]) tree = Gtk.TreeView(model=self.store) tree.append_column(column) # self.add(tree) self.show_all() # Timer it = self.store.append([0]) self.timeout_id = GLib.timeout_add(100, self.on_timeout, it) def on_timeout(self, it): new_value = self.store[it][0] + 1 if new_value > 100: return False self.store[it][0] = new_value return True 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)
GtkCellRendererSpinner
GtkCellRendererSpinner はいわゆるウエイト表示。昔の Windows では砂時計、今はクルクル回るアレです。
active プロパティで表示し pulse プロパティで回り具合を調節します。
#!/usr/bin/env python3 import sys, gi gi.require_version('Gtk', '3.0') from gi.repository import Gtk, GLib class Win(Gtk.ApplicationWindow): ''' レンダラ ''' def __init__(self, app): Gtk.ApplicationWindow.__init__(self, application=app, title='Py') # Renderer cell = Gtk.CellRendererSpinner(active=True, size=Gtk.IconSize.DIALOG) # Column column = Gtk.TreeViewColumn(title='spinner') column.pack_start(cell, True) column.add_attribute(cell, 'pulse', 0) # ListStore self.store = Gtk.ListStore.new([int]) tree = Gtk.TreeView(model=self.store) tree.append_column(column) # self.add(tree) self.show_all() # Timer it = self.store.append([0]) self.timeout_id = GLib.timeout_add(20, self.on_timeout, it) def on_timeout(self, it): new_value = self.store[it][0] + 1 if new_value > 100: return False self.store[it][0] = new_value return True 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)
GtkCellRendererToggle
GtkCellRendererToggle はその名のとおりチェックボックスです。チェックボックスをクリックすると toggled シグナルが発生しますが表示は変わりません。
チェック状態を変更したい場合は以下のように自力で行う必要があります。
#!/usr/bin/env python3 import sys, gi gi.require_version('Gtk', '3.0') from gi.repository import Gtk, GLib class Win(Gtk.ApplicationWindow): ''' レンダラ ''' def __init__(self, app): Gtk.ApplicationWindow.__init__(self, application=app, title='Py') # Renderer cell_toggle = Gtk.CellRendererToggle() cell_text = Gtk.CellRendererText() # Signal cell_toggle.connect('toggled', self.on_toggled) # Column column_toggle = Gtk.TreeViewColumn(title='!') column_toggle.pack_start(cell_toggle, True) column_toggle.add_attribute(cell_toggle, 'active', 0) column_text = Gtk.TreeViewColumn(title='欲しいバイクを選んでね') column_text.pack_start(cell_text, True) column_text.add_attribute(cell_text, 'text', 1) # ListStore self.store = Gtk.ListStore.new([bool, str]) for s in ['刀', 'Vストローム', '隼', 'GSX-R1000R']: self.store.append([False, s]) tree = Gtk.TreeView(model=self.store) tree.append_column(column_toggle) tree.append_column(column_text) # self.add(tree) self.show_all() def on_toggled(self, widget, path): self.store[path][0] = not self.store[path][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)
Copyright(C) sasakima-nao All rights reserved 2002 --- 2024.