Create  Edit  FrontPage  Index  Search  Changes  History  RSS  Login

tut-treeview-renderer-celldatafunc

Cell Data Functions

A cell data function is a block of code that is called for a specific cell renderer for each single row before that row is rendered. It gives you maximum control over what exactly is going to be rendered, as you can set the cell renderer's properties just like you want to have them. Remember not only to set a property if you want it to be active, but also to unset a property if it should not be active (and it might have been set in the previous row).

Cell data functions are often used if you want more fine-grained control over what is to be displayed, or if the standard way to display something is not quite like you want it to be. A case in point are floating point numbers. If you want floating point numbers to be displayed in a certain way, say with only one digit after the colon/comma, then you need to use a cell data function. Use Gtk::TreeViewColumn#set_cell_data_func to set up a cell data function for a particular cell renderer. Here is an example:

liststore = Gtk::ListStore.new(String, Float)

renderer = Gtk::CellRendererText.new

col = Gtk::TreeViewColumn.new("Age", renderer)

col.set_cell_data_func(renderer) do |col, renderer, model, iter|
  # display age with only one digit 
  renderer.text = sprintf("%.1f", iter[2])
  # display cell in red if the age is below 18
  if iter[2] < 18
    renderer.background = "red"
  else
    renderer.background = nil
  end
end

Following is a simple example program demonstrating the use of set_cell_data_func function. Note that this function is associated with a particular cell renderer which is mapped to a tree view column via the column, associated to the renderer by Gtk::TreeViewColumn.new, and subsequently by the Gtk::TreeView#append_column(column) statement; so all render, column, which is associated with the set_cell_data_func function, and the tree view are all connected. The block associated with the set_cell_data_func function is executed for every row for that particular view column.

#!/usr/bin/env ruby
require 'gtk2'

# Add three columns to the GtkTreeView. All three of the
# columns will be displayed as text, although one is a boolean
# value and another is an integer.
def setup_tree_view(treeview)
  # Create a new GtkCellRendererText, add it to the tree
  # view column and append the column to the tree view.
  renderer = Gtk::CellRendererText.new
  column   = Gtk::TreeViewColumn.new("Buy", renderer,  :text => BUY_IT)
  column.set_cell_data_func(renderer) do |col, renderer, model, iter|
    renderer.background = iter[BUY_IT] ? "red" : nil
  end
  treeview.append_column(column)

  renderer = Gtk::CellRendererText.new
  column   = Gtk::TreeViewColumn.new("Count", renderer, :text => QUANTITY)
  treeview.append_column(column)

  renderer = Gtk::CellRendererText.new
  column   = Gtk::TreeViewColumn.new("Product", renderer, :text => PRODUCT)
  treeview.append_column(column)
end

class GroceryItem
  attr_accessor :buy, :quantity, :product
  def initialize(b, q, p); @buy, @quantity, @product = b, q, p; end
end
BUY_IT = 0; QUANTITY = 1; PRODUCT  = 2

list = Array.new
list[0] = GroceryItem.new(true,  1, "Paper Towels") 
list[1] = GroceryItem.new(true,  2, "Bread")
list[2] = GroceryItem.new(false, 1, "Butter")
list[3] = GroceryItem.new(true,  1, "Milk")
list[4] = GroceryItem.new(false, 3, "Chips")
list[5] = GroceryItem.new(true,  4, "Soda") 

# Create a new tree model with three columns, as Boolean,
# integer and string.
store = Gtk::ListStore.new(TrueClass, Integer, String)
treeview = Gtk::TreeView.new(store) # Add the tree model (store) to the tree view
setup_tree_view(treeview)

# Add all of the products to the GtkListStore.
list.each_with_index do |e, i|
    iter = store.append
    store.set_value(iter, BUY_IT,   list[i].buy)	# iter[BUY_IT]   = list[i].buy
    store.set_value(iter, QUANTITY, list[i].quantity)	# iter[QUANTITY] = list[i].quantity
    store.set_value(iter, PRODUCT,  list[i].product)	# iter[PRODUCT]  = list[i].product
end

scrolled_win = Gtk::ScrolledWindow.new
scrolled_win.add(treeview)
scrolled_win.set_policy(Gtk::POLICY_AUTOMATIC, Gtk::POLICY_AUTOMATIC)

window = Gtk::Window.new("Grocery List")
window.resizable = true
window.border_width = 10
window.signal_connect('destroy') { Gtk.main_quit }
window.set_size_request(250, 165)
window.add(scrolled_win)
window.show_all
Gtk.main
Last modified:2012/08/14 06:35:10
Keyword(s):
References:[tut-treeview] [tut-treeview-renderer-attributes] [tut-treeview-renderer-types]