PHP-GTK2 Newsletter

PHP-GTK2 Tips & Techniques
FREE Newsletter
by kksou



Sample Code 138: How to edit items in GtkTreeView - using built in treeview edit - Part 1?
Written by kksou   
Tuesday, 09 January 2007
Problem

Suppose your current application requires editing of items in treeview. There are many ways of doing this. In the article How to edit items in GtkTreeView - using popup dialog?, we used a popup form. On double-clicking a row, a popup dialog is displayed for editing.

In this article, we let user edit directly in the treeview as shown below:

How to edit items in GtkTreeView - using built in treeview edit - Part 1?


Solution

Sample Code
1   
2   
3   
4   
5   
6   
7   
8   
9   
10   
11   
12   
13   
14   
15   
16   
17   
18   
19   
20   
21   
22   
23   
24   
25   
26   
27   
28   
29   
30   
31   
32   
33   
34   
35   
36   
37   
38   
39   
40   
41   
42   
43   
44   
45   
46   
47   
48   
49   
50   
51   
52   
53   
54   
55   
56   
57   
58   
59   
60   
61   
62   
63   
64   
65   
66   
67   
68   
69   
70   
71   
72   
73   
74   
75   
76   
77   
78   
79   
80   
81   
82   
83   
84   
<?php
$window = new GtkWindow();
$window->set_size_request(400, 200);
$window->connect_simple('destroy', array('Gtk','main_quit'));
$window->add($vbox = new GtkVBox());

// display title
$title = new GtkLabel("Edit Items in GtkTreeView\n".
"using built-in-treeview edit - Part 1");
$title->modify_font(new PangoFontDescription("Times New Roman Italic 10"));
$title->modify_fg(Gtk::STATE_NORMAL, GdkColor::parse("#0000ff"));
$title->set_size_request(-1, 40);
$title->set_justify(Gtk::JUSTIFY_CENTER);
$alignment = new GtkAlignment(0.5, 0, 0, 0);
$alignment->add($title);
$vbox->pack_start($alignment, 0, 0);
$vbox->pack_start(new GtkLabel(), 0, 0);

// the 2D table
$data = array(
array('id0', 'item 42', 2, 3.1),
array('id1', 'item 36', 20, 6.21),
array('id2', 'item 21', 8, 9.36),
array('id3', 'item 10', 11, 12.4),
array('id4', 'item 7', 5, 15.5),
array('id5', 'item 4', 17, 18.6),
array('id6', 'item 3', 20, 21.73));

display_table ($vbox, $data);

$window->show_all();
Gtk::main();

function display_table($vbox, $data) {

    // Set up a scroll window
    $scrolled_win = new GtkScrolledWindow();
    $scrolled_win->set_policy( Gtk::POLICY_AUTOMATIC,
        Gtk::POLICY_AUTOMATIC);
    $vbox->pack_start($scrolled_win);

    // Creates the list store
    if (defined("GObject::TYPE_STRING")) {
        $model = new GtkListStore(GObject::TYPE_STRING, GObject::TYPE_STRING,
                    GObject::TYPE_LONG, GObject::TYPE_DOUBLE);
    } else {
        $model = new GtkListStore(Gtk::TYPE_STRING, Gtk::TYPE_STRING,
                    Gtk::TYPE_LONG, Gtk::TYPE_DOUBLE);
    }
    $field_header = array('Item Number', 'Description', 'Qty', 'Price');
    $field_justification = array(0.5, 0.0, 0.5, 1.0);

    // Creates the view to display the list store
    $view = new GtkTreeView($model);
    $scrolled_win->add($view);

    // Creates the columns
    for ($col=0; $col<count($field_header); ++$col) {
        $cell_renderer = new GtkCellRendererText();
        $cell_renderer->set_property("xalign", $field_justification[$col]);
        $cell_renderer->set_property('editable', true); // note 1
        $cell_renderer->connect("edited", "on_edit_done", $view, $col); // note 2

        $column = new GtkTreeViewColumn($field_header[$col],
            $cell_renderer, 'text', $col);
        $column->set_alignment($field_justification[$col]);
        $column->set_sort_column_id($col);

        // set the header font and color
        $label = new GtkLabel($field_header[$col]);
        $label->modify_font(new PangoFontDescription("Arial Bold"));
        $label->modify_fg(Gtk::STATE_NORMAL, GdkColor::parse("#0000FF"));
        $column->set_widget($label);
        $label->show();

        // setup self-defined function to display alternate row color
        $column->set_cell_data_func($cell_renderer, "format_col", $col);
        $view->append_column($column);
    }

    // pupulates the data
    for ($row=0; $row<count($data); ++$row) {
        $values = array();
        for ($col=0; $col<count($data[$row]); ++$col) {
  • Note that this is only 70% of the sample code. You have to be a registered member to see the entire sample code. Please login or register.
  • Registration is free and immediate.
  • Have some doubt about the registration? Please read this forum article.
Explanation
  1. Allow editing.
  2. Register 'edited' signal to know when the user has finished editing.
  3. Get the model.
  4. Get the iter.
  5. Update the new value back to the model.

Note
  • You can begin editing a field by clicking the field, by pressing Enter, or by pressing Space.
  • You can end the edit by clicking another field or by pressing Enter.
  • If you click on any field in the last column (Price), and just press return, you will find that the price changed to $0.00. This is because of the '$' sign in front of the number. We'll fix this in Part 2.

You may also want to compare this method with How to edit items in GtkTreeView - using popup dialog?


Related Links

User reviews   Average user ratings:    4.5   (from 13 users)
  1. Devon Y from USA
    February 18, 2007 8:42pm

    I believe I may have found a bug...
    When I add sorting to the columns, as shown in
    http://www.kksou.com/php-gtk2/articles/sort-treeview-using-GtkTreeModelSort.php

    I then open the table, change the sort, then edit a cell. After the edit is done, the cell value is updated in a different row. It appears that the row information accessed in
    $iter = $model->get_iter_from_string($path);
    does not update during the sort operation. How can I correct this?

  2. kksou
    February 19, 2007 8:42am

    The modelsort is a virtual model. We have to update the values back to the base model. We can use GtkTreemodelsort::convert_iter_to_child_iter() to get the iter of the base model.

    Here's an example that shows editing of treeview with GtkTreeModelSort:
    http://www.kksou.com/php-gtk2/articles/edit-items-in-GtkTreeView---using-built-in-treeview-edit---Part-3-with-GtkTreeModelSort.php

  3. Devon Y from USA
    February 19, 2007 6:49pm

    That works perfectly. Thanks for the prompt response!

  4. Anderson from Brazil
    April 03, 2007 7:00am

    Hello, i am using this function on my application, to create columns in the treeview. I included the source code from your sample to
    edit cells.But when i edit one cell, all cells in the selected row are changed with the same value that i modified. I can't find the bug
    and, if possible, could you help me?

    I attached the source code below:


    function add_coluna_treeview($fields,$treeview,$size=null,$color=null,$font=null,$table=null){

    //the text renderer is used to display text
    $cell_renderer = new GtkCellRendererText();
    if($color){
    $cell_renderer->set_property("foreground-gdk",$color);
    }
    if($font){
    $cell_renderer->set_property('font', $font);
    }
    for($i=0;$iset_resizable(true);
    $col[$i]->set_sort_column_id($i);

    if($size[$i]){
    $col[$i]->set_min_width($size[$i]);
    $col[$i]->set_max_width($size[$i]);
    }
    if($size[$i]=="0"){
    $col[$i]->set_visible(false);
    }
    if($table=="mercadorias"){
    $col[$i]->set_cell_data_func($cell_renderer, array($this,'color_treeview_mercadorias'));
    }
    if(($table=="atividades")){
    $cell_renderer->set_property('editable', true); // note 1
    $cell_renderer->connect("edited", array($this,"on_edit_done"), $treeview, $i);
    }
    $col[$i]->set_cell_data_func($cell_renderer, array($this,"format_col"), $i);
    $treeview->append_column($col[$i]);
    }
    return $col;
    }


    function on_edit_done($cell, $path, $new_text, $view, $col){

    $model=$view->get_model();
    $iter = $model->get_iter_from_string($path);
    $model->set($iter, $col, $new_text);
    }

  5. Dysmas
    April 04, 2008 8:47am

  6. Tarvin Colmar
    April 28, 2008 6:46am

  7. Nick Charsley
    May 09, 2008 12:11pm

  8. Peter Shaw
    June 03, 2008 2:35am

  9. JD
    November 25, 2009 9:03am

    In my app I have a GtkTreeView with a GtkListStore behind it, and the cell renderer is set to "editable" as above. However, when the users try to edit values in the editable column, they have to click each cell several times before it becomes editable.

    Is there a way of getting an editable cell-renderer to respond to your first click, instead of (in some cases) the third or fourth click?

  10. JD
    November 25, 2009 9:19am

    N.B. I've already set up a signal handler for the cursor-changed event of the tree view, and then in the signal handler I use get_cursor() to get the row # and the active GtkTreeViewColumn, but I can't work out what to do next! Something to do with GtkCellRenderer::start_editing(), perhaps?

  11. JD
    November 25, 2009 1:56pm

    This is the signal handler that I was going on about earlier. I get as far as identifying that the cell renderer of the selected column is editable, but then I don't know how to proceed from there.

    public function onTreeViewCursorChanged(GtkTreeView &$objTreeView)
    {
    list($intRow, $objTreeViewColumn) = $objTreeView->get_cursor();

    if ($objTreeViewColumn !== null)
    {
    foreach ($objTreeViewColumn->get_cell_renderers() as $objRenderer)
    {
    if ($objRenderer->get_property('editable'))
    {
    // $objRenderer->start_editing(?, ?, ?, ?, ?, ?);
    }
    }
    }
    }

  12. Pierre Fauconnier
    December 16, 2009 4:25am
    > in reply to JD

    1- must click onto the caption (not so obvious ;)
    2- add a popup menu then use "set_cursor_on_cell", because imho "start_editing" is a wrong way.

    Regards,
    Pierre.

  13. Rau
    June 30, 2010 7:36am
    is there a bug with special chracters?

    When I run the example, (S.O. windows XP SP3,PHP 5.2.13 and PHP-GTK) I get a Fatal error:

    You have selected item 10: 11 (12,4)

    Warning: Could not convert string from UTF-8 in C:\php-gtk2\ListaEdit.php on line 120


    Fatal error: Uncaught exception 'PhpGtkGErrorException' with message 'Invalid byte sequence in conve
    rsion input' in C:\hrmb\VersionXP\php-gtk2\ListaEdit.php:32
    Stack trace:
    #0 C:\hrmb\VersionXP\php-gtk2\ListaEdit.php(32): Gtk::main()
    #1 {main}
    thrown in C:\hrmb\VersionXP\php-gtk2\ListaEdit.php on line 32

    When I type an special character (ñ or Ñ).

    How can I fix this problem?

Note: You have to be a registered member to leave a comment. Free registration here.

 
< Prev   Next >

Blog - Forum - Privacy Policy - Contact Us
Copyright © 2006-2009. kksou.com. All Rights Reserved