Treeviews and Cell Renderer Properties - Practical PHP-GTK

I get this question a lot - "How do I change the background color of a single cell in a treeview?"

If you look around you'll see a couple of ways of doing this using display callbacks and other highly processor and memory intensive methods - but there's a much simpler way.

Let's start at the beginning. Every cell displayed in a GtkTreeView has a "Cell Renderer" that takes data from the Datastore and displays it. There are different types of Renderers with specific purposes. A GtkCellRendererText displays, well, text. A GtkCellRendererPixbuf displays an image (in the form of a GdkPixbuf), a GtkCellRendererProgress displays a progress bar. One thing you probably didn't know is that these have things called "properties" that you can manipulate.

Unfortunately these are not well documented in the PHP-GTK2 documentation. But remember, it's all GTK underneath and there are some great docs at gtk.org and at pygtk.org. See the huge list of things you can change in a text cell renderer? You can manipulate anything from background color to how the text wraps.

Now for the cool part - you can attach the value of a column in your datastore to one of the available properties. In fact, you're doing this every time you create a treeview with a text column, you're attaching a datastore columns value to the "text" property! Why is this cool? Then when you change the value of the item in the datastore, the treeview "magically" updates.

So let's look at a little example -

[php]
// Our callback to change the value of the datastore "color" column when you double click
// Also adds an additional row to the datastore for fun
function changecolor($treeview, $path, $column) {
$store = $treeview->get_model();
$iter = $store->get_iter($path);
$store->set($iter, 2, '#FF0000');
$store->append(array('New Item', 0, '#FFFFFF'));
}

// create our datastore - columns are item, value, color
$store = new GtkListStore(Gobject::TYPE_STRING, Gobject::TYPE_LONG, Gobject::TYPE_STRING);

// fill up our store with random data
for ($i = 1; $i = 10; $i++) {
$store->append(array('Item ' . $i, $i, '#FFFFFF'));
}

// create our treeview
$treeview = new GtkTreeView($store);

// create a cell renderer for items - this one we want to change color
$cell_renderer1 = new GtkCellRendererText();

// create the column, binding the text attribute to the 0 datastore column, and the background attribute to the 2 column
// remember a datastore is zero indexed
$column1 = new GtkTreeViewColumn('item', $cell_renderer1, 'text', 0, 'background', 2);
$treeview->append_column($column1);

// since we DON'T want this to change colors we need a NEW cell renderer
$cell_renderer2 = new GtkCellRendererText();

// only bind to text
$column2 = new GtkTreeViewColumn('value', $cell_renderer2, 'text', 1);
$treeview->append_column($column2);

// attach a callback to change color on double click
$treeview->connect('row-activated', 'changecolor');

// Create a quick window
$wnd = new GtkWindow();
$wnd->set_title('Example');
$wnd->connect_simple('destroy', array('gtk', 'main_quit'));

//to make the view scrollable, we need a scrolled window
$scrwnd = new GtkScrolledWindow();
$scrwnd->set_policy(Gtk::POLICY_AUTOMATIC, Gtk::POLICY_AUTOMATIC);
$scrwnd->add($treeview);

$wnd->add($scrwnd);
$wnd->set_default_size(250, 200);
$wnd->show_all();
Gtk::main();
[/php]

Below you can see it in action

Moral of the story? Don't worry about callbacks and complications, just put the formatting data in your datastore and bind it to your cellrenderers. You can do some really interesting stuff if you use the right tools.

(btw, a little recruitment... if you want a job as the King/Queen of PHP-GTK documentation give one of the mailing lists a ping - you'll need to learn/know docbook and deal with the phpdoc people and the new Phd doc system Our current doc King is lacking internet access atm)

Comments

Franco G.Holmann

Elizabeth:
Very useful article.
Have installed Php-GTK 2.0.1 and have not been able to activate extension php_gtk_html2.dll at all. Use Windows
XP and Windows 7.
Read about renaming a lib... to gtk... but still I get
a missing ORBIT.dll file missing.
Then I read that using php-gtk 2.0 beta. Things somehow
work with that version. Tried to get php-gtk 2.0 beta and could not find it anywhere.
Your comments will be appreciated.
A solution will be fantastic
Regards
Franco

2011-08-23 3:18 pm

Post a Reply