翻訳して勉強するGtkチュートリアル第13章は CellRenderers です。ようやく、このチュートリアルの後半に差し掛かりました。
Gtk.CellRenderer ウィジェットは Gtk.TreeView や Gtk.ComboBox などのウィジェット内の情報を表示するために使われます。これらのウィジェットは関連するウィジェットと密接に連携して動作し、非常に強力で、大量のデータをさまざまな方法で表示するための多くの設定オプションを備えています。
Gtk.CellRenderer ウィジェットは7つあり、それぞれの目的に合わせて使うことができます。
- Gtk.CellRendererText
- Gtk.CellRendererToggle
- Gtk.CellRendererPixbuf
- Gtk.CellRendererCombo
- Gtk.CellRendererProgress
- Gtk.CellRendererSpinner
- Gtk.CellRendererSpin
- Gtk.CellRendererAccel
13.1. CellRendererText
Gtk.CellRendererText は、プロパティによって提供されるフォント、色、スタイルの情報を用いて、与えられたテキストをセル内にレンダリングします。長過ぎるテキストは"ellipsize" プロパティで楕円化が許可されている場合は、楕円化されます。
デフォルトでは、Gtk.CellRendererText ウィジェット内のテキストは編集可能ではありません。これは “editable” プロパティの値を True に設定することで変更できます。
13.1.1. 例
# tut13-01.py
# CellRendererText サンプル
import gi
gi.require_version("Gtk", "3.0")
from gi.repository import Gtk
class CellRendererTextWindow(Gtk.Window):
def __init__(self):
Gtk.Window.__init__(self, title="CellRendererText Example")
self.set_default_size(400, 150)
self.liststore = Gtk.ListStore(str, str)
self.liststore.append(["Fedora", "https://fedoraproject.org/"])
self.liststore.append(["Slackware", "http://www.slackware.com/"])
self.liststore.append(["Sidux", "http://sidux.com/"])
treeview = Gtk.TreeView(model=self.liststore)
renderer_text = Gtk.CellRendererText()
column_text = Gtk.TreeViewColumn("Text", renderer_text, text=0)
treeview.append_column(column_text)
renderer_editabletext = Gtk.CellRendererText()
renderer_editabletext.set_property("editable", True)
column_editabletext = Gtk.TreeViewColumn(
"Editable Text", renderer_editabletext, text=1
)
treeview.append_column(column_editabletext)
renderer_editabletext.connect("edited", self.text_edited)
self.add(treeview)
def text_edited(self, widget, path, text):
self.liststore[path][1] = text
win = CellRendererTextWindow()
win.connect("destroy", Gtk.main_quit)
win.show_all()
Gtk.main()
13.2. CellRendererToggle
Gtk.CellRendererToggle はセル内のトグルボタンをレンダリングします。ボタンは “radio” プロパティに応じて、ラジオボタンかチェックボタンとして描画されます。アクティベートされると、“toggled” シグナルを発します。
Gtk.CellRendererToggle はアクティブと非アクティブの2つの状態を持つことができるので、セルレンダラの “active” プロパティをモデルのブール値にバインドして、チェックボタンにモデルの状態を反映させたい場合が多いでしょう。
13.2.1. 例
# tut13-01.py
# CellRendererToggle サンプル
import gi
gi.require_version("Gtk", "3.0")
from gi.repository import Gtk
class CellRendererToggleWindow(Gtk.Window):
def __init__(self):
Gtk.Window.__init__(self, title="CellRendererToggle Example")
self.set_default_size(400, 150)
self.liststore = Gtk.ListStore(str, bool, bool)
self.liststore.append(["Debian", False, True])
self.liststore.append(["OpenSuse", True, False])
self.liststore.append(["Fedora", False, False])
treeview = Gtk.TreeView(model=self.liststore)
renderer_text = Gtk.CellRendererText()
column_text = Gtk.TreeViewColumn("Text", renderer_text, text=0)
treeview.append_column(column_text)
renderer_toggle = Gtk.CellRendererToggle()
renderer_toggle.connect("toggled", self.on_cell_toggled)
column_toggle = Gtk.TreeViewColumn("Toggle", renderer_toggle, active=1)
treeview.append_column(column_toggle)
renderer_radio = Gtk.CellRendererToggle()
renderer_radio.set_radio(True)
renderer_radio.connect("toggled", self.on_cell_radio_toggled)
column_radio = Gtk.TreeViewColumn("Radio", renderer_radio, active=2)
treeview.append_column(column_radio)
self.add(treeview)
def on_cell_toggled(self, widget, path):
self.liststore[path][1] = not self.liststore[path][1]
def on_cell_radio_toggled(self, widget, path):
selected_path = Gtk.TreePath(path)
for row in self.liststore:
row[2] = row.path == selected_path
win = CellRendererToggleWindow()
win.connect("destroy", Gtk.main_quit)
win.show_all()
Gtk.main()
13.3. CellRendererPixbuf
Gtk.CellRendererPixbuf を使ってセル内の画像をレンダリングすることができます。これにより、与えられた Gdk.Pixbuf ( “pixbuf” プロパティで設定) あるいは名前付きアイコン ( “icon-name” プロパティで設定) のいずれかをレンダリングできます。
13.3.1. 例
# tut13-03.py
# CellRendererPixbuf サンプル
import gi
gi.require_version("Gtk", "3.0")
from gi.repository import Gtk
class CellRendererPixbufWindow(Gtk.Window):
def __init__(self):
Gtk.Window.__init__(self, title="CellRendererPixbuf Example")
self.set_default_size(400, 150)
self.liststore = Gtk.ListStore(str, str)
self.liststore.append(["New", "document-new"])
self.liststore.append(["Open", "document-open"])
self.liststore.append(["Save", "document-save"])
treeview = Gtk.TreeView(model=self.liststore)
renderer_text = Gtk.CellRendererText()
column_text = Gtk.TreeViewColumn("Text", renderer_text, text=0)
treeview.append_column(column_text)
renderer_pixbuf = Gtk.CellRendererPixbuf()
column_pixbuf = Gtk.TreeViewColumn("Image", renderer_pixbuf, icon_name=1)
treeview.append_column(column_pixbuf)
self.add(treeview)
win = CellRendererPixbufWindow()
win.connect("destroy", Gtk.main_quit)
win.show_all()
Gtk.main()
13.4. CellRendererCombo
Gtk.CellRendererCombo は、 Gtk.CellRendererText と同じように派生元のセル内のテキストをレンダリングします。しかし CellRendererText がテキストを編集するためのシンプルなエントリを提供しているのに対し、Gtk.CellRendererCombo はテキストを編集するための Gtk.ComboBox ウィジェットを提供しています。コンボボックスに表示される値は、“model” プロパティで指定された Gtk.TreeModel から取得します。
Combo-cell-rendererは、コンボボックスにtext-cell-rendererを追加し、その “text-column” プロパティで指定された列を表示するように設定します。
Gtk.CellRendererCombo は2つのモードで動作します。“has-entry” プロパティの値によって、関連する Gtk.Entry ウィジェットの有無に関わらず使うことができます。
13.4.1. 例
# tut13-04.py
# CellRendererCombo サンプル
import gi
gi.require_version("Gtk", "3.0")
from gi.repository import Gtk
class CellRendererComboWindow(Gtk.Window):
def __init__(self):
Gtk.Window.__init__(self, title="CellRendererCombo Example")
self.set_default_size(400, 150)
liststore_manufacturers = Gtk.ListStore(str)
manufacturers = ["Sony", "LG", "Panasonic", "Toshiba", "Nokia", "Samsung"]
for item in manufacturers:
liststore_manufacturers.append([item])
self.liststore_hardware = Gtk.ListStore(str, str)
self.liststore_hardware.append(["Television", "Samsung"])
self.liststore_hardware.append(["Mobile Phone", "LG"])
self.liststore_hardware.append(["DVD Player", "Sony"])
treeview = Gtk.TreeView(model=self.liststore_hardware)
renderer_text = Gtk.CellRendererText()
column_text = Gtk.TreeViewColumn("Text", renderer_text, text=0)
treeview.append_column(column_text)
renderer_combo = Gtk.CellRendererCombo()
renderer_combo.set_property("editable", True)
renderer_combo.set_property("model", liststore_manufacturers)
renderer_combo.set_property("text-column", 0)
renderer_combo.set_property("has-entry", False)
renderer_combo.connect("edited", self.on_combo_changed)
column_combo = Gtk.TreeViewColumn("Combo", renderer_combo, text=1)
treeview.append_column(column_combo)
self.add(treeview)
def on_combo_changed(self, widget, path, text):
self.liststore_hardware[path][1] = text
win = CellRendererComboWindow()
win.connect("destroy", Gtk.main_quit)
win.show_all()
Gtk.main()
13.5. CellRendererProgress
Gtk.CellRendererProgress は数値をセル内のプログレスバーとしてレンダリングします。プログレスバーの上にテキストを表示することもできます。
“value” プロパティを変更することで、プログレスバーのパーセンテージ値を変更できます。Gtk.ProgressBar と同様に、“value “プロパティの代わりに “pulse “プロパティをインクリメント(変数を1増加)することでアクティビティモードを有効にすることができます。
13.5.1. 例
# tut13-05.py
# CellRendererProgress サンプル
import gi
gi.require_version("Gtk", "3.0")
from gi.repository import Gtk, GLib
class CellRendererProgressWindow(Gtk.Window):
def __init__(self):
Gtk.Window.__init__(self, title="CellRendererProgress Example")
self.set_default_size(400, 150)
self.liststore = Gtk.ListStore(str, int, bool)
self.current_iter = self.liststore.append(["Sabayon", 0, False])
self.liststore.append(["Zenwalk", 0, False])
self.liststore.append(["SimplyMepis", 0, False])
treeview = Gtk.TreeView(model=self.liststore)
renderer_text = Gtk.CellRendererText()
column_text = Gtk.TreeViewColumn("Text", renderer_text, text=0)
treeview.append_column(column_text)
renderer_progress = Gtk.CellRendererProgress()
column_progress = Gtk.TreeViewColumn(
"Progress", renderer_progress, value=1, inverted=2
)
treeview.append_column(column_progress)
renderer_toggle = Gtk.CellRendererToggle()
renderer_toggle.connect("toggled", self.on_inverted_toggled)
column_toggle = Gtk.TreeViewColumn("Inverted", renderer_toggle, active=2)
treeview.append_column(column_toggle)
self.add(treeview)
self.timeout_id = GLib.timeout_add(100, self.on_timeout, None)
def on_inverted_toggled(self, widget, path):
self.liststore[path][2] = not self.liststore[path][2]
def on_timeout(self, user_data):
new_value = self.liststore[self.current_iter][1] + 1
if new_value > 100:
self.current_iter = self.liststore.iter_next(self.current_iter)
if self.current_iter is None:
self.reset_model()
new_value = self.liststore[self.current_iter][1] + 1
self.liststore[self.current_iter][1] = new_value
return True
def reset_model(self):
for row in self.liststore:
row[1] = 0
self.current_iter = self.liststore.get_iter_first()
win = CellRendererProgressWindow()
win.connect("destroy", Gtk.main_quit)
win.show_all()
Gtk.main()
13.6. CellRendererSpin
Gtk.CellRendererSpin は、Gtk.CellRendererText から派生したもので、セル内のテキストをレンダリングします。しかし CellRendererText がテキストを編集するためのシンプルなエントリを提供するのに対して、Gtk.CellRendererSpin は Gtk.SpinButton ウィジェットを提供します。もちろん、これはテキストが浮動小数点数として解析可能でなければならないことを意味します。
スピンボタンの範囲は、セルレンダラの調整プロパティから取得され、明示的に設定することも、セルレンダラのすべてのプロパティと同様にツリーモデルのカラムにマッピングすることもできます。Gtk.CellRendererSpin には、上昇率と表示桁数のプロパティもあります。
13.6.1. 例
# tut13-06.py
# CellRendererSpin サンプル
import gi
gi.require_version("Gtk", "3.0")
from gi.repository import Gtk
class CellRendererSpinWindow(Gtk.Window):
def __init__(self):
Gtk.Window.__init__(self, title="CellRendererSpin Example")
self.set_default_size(400, 150)
self.liststore = Gtk.ListStore(str, int)
self.liststore.append(["Oranges", 5])
self.liststore.append(["Apples", 4])
self.liststore.append(["Bananas", 2])
treeview = Gtk.TreeView(model=self.liststore)
renderer_text = Gtk.CellRendererText()
column_text = Gtk.TreeViewColumn("Fruit", renderer_text, text=0)
treeview.append_column(column_text)
renderer_spin = Gtk.CellRendererSpin()
renderer_spin.connect("edited", self.on_amount_edited)
renderer_spin.set_property("editable", True)
adjustment = Gtk.Adjustment(0, 0, 100, 1, 10, 0)
renderer_spin.set_property("adjustment", adjustment)
column_spin = Gtk.TreeViewColumn("Amount", renderer_spin, text=1)
treeview.append_column(column_spin)
self.add(treeview)
def on_amount_edited(self, widget, path, value):
self.liststore[path][1] = int(value)
win = CellRendererSpinWindow()
win.connect("destroy", Gtk.main_quit)
win.show_all()
Gtk.main()