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 --- 2025.