Unless I misunderstand what you're doing ... you're making things far more
complicated for yourself than they need to be.

Your sub process_combo() receives: $tree_column, $renderer, $model, $iter.
Your $model has both the text and the ID. The ID is in position 0, and the
text that's displayed is in column 1.

To get the ID, you'd go:

my $id = $model->get( $iter, 0 );

To get the string, you'd go:

my $string = $model->get( $iter, 1 );

If your IDs and strings come from a database, use my
Gtk2::Ex::Datasheet::DBI ;) Big updates coming soon ...

Dan


On Sat, Feb 8, 2014 at 2:09 AM, RAPPAZ Francois <francois.rap...@unifr.ch>wrote:

> Hi there,
>
> I'm trying to use a CellRendererCombo in a tree. The combo has 2 columns
> one which holds a key (numeric) not displayed and, the visible column which
> holds a text.
>
> The only way I got it working is with two sub that searches the whole
> combo content for a match and then display the value found in the tree, or
> take the value from the tree to display the corresponding row in the combo.
>
> There is a similar code in perlmonks
> http://www.perlmonks.org/?node_id=952244
>
> Is there no short way to do this ?
>
> My code is below.
>
> Thanks for any help
>
> François
>
>
> #! /usr/bin/perl -w
>
> use strict;
> use Gtk2 '-init';
> use Glib qw/TRUE FALSE/;
> use Data::Dumper;
>
> my %render = (
>         text => sub { return Gtk2::CellRendererText->new; },
>         hidden => sub { return Gtk2::CellRendererText->new;   },
>         number => sub { return Gtk2::CellRendererText->new;    },
>         toggle => sub { return Gtk2::CellRendererToggle->new;   },
>         combo => sub {  return Gtk2::CellRendererCombo->new;   },
>         progress => sub { return Gtk2::CellRendererProgress->new;   },
>         status_column => sub { return Gtk2::CellRendererPixbuf->new; },
>         image => sub { return Gtk2::CellRendererPixbuf->new;   },
> );
>
> my %signals = (
>         'Gtk2::CellRendererText' => [ 'edited' , sub { cell_edited(@_)}],
>         ' Gtk2::CellRendererToggle' => ['toggled',  sub {
> toggle_edited(@_)}],
>         'Gtk2::CellRendererCombo' => ['edited', sub { combo_edited(@_)}],
>
> );
>
> my @fields = ("a","b","c");
>
> my %combo = (1 => "one", 2 => "two", 3 => "three");
>
> #standard window creation, placement, and signal connecting my $window =
> Gtk2::Window->new('toplevel'); $window->signal_connect('delete_event' =>
> sub { Gtk2->main_quit; }); $window->set_border_width(5);
> $window->set_position('center_always');
>
> #this vbox will geturn the bulk of the gui my $vbox = &ret_vbox();
>
> #add and show the vbox
> $window->add($vbox);
> $window->show();
>
> #our main event-loop
> Gtk2->main;
>
>
> sub ret_vbox {
>
> my $vbox = Gtk2::VBox->new(FALSE,5);
> $vbox->set_size_request (300, 300);
>
>         #this is one of the provided base Gtk2::TreeModel classes.
> my $tree = Gtk2::TreeView->new();
> my $pos=0;
>
> my @listedef;
>
>         foreach my $field (@fields) {
>
>                 my $renderer =  ($pos == 0 ?
> $render{"combo"}():$render{"text"}());
>
>                  my $cell_ref = ref $renderer;
>                 print "$cell_ref\n";
>
>                 $renderer->set( editable => TRUE );
>                 if ($pos == 0){
>                         setup_combo($pos, $field, $renderer);
>
>                 } #else {
>                 #$renderer->signal_connect (edited => sub {
> cell_edited(@_)}, $tree);
>                 #}
>                 $renderer->{column}=$pos;
>                 my $col =
>  Gtk2::TreeViewColumn->new_with_attributes($field, $renderer, "text" =>
> $pos);
>                 $tree->append_column($col);
>
>                  my $label = Gtk2::Label->new;
>                  $label->set_text("$field");
>                  $label->visible( 1 );
>                 $col->set_widget($label);
>                 push @listedef, "Glib::String";
>
>                 if (exists $signals{$cell_ref}) {
>                             my $coderef =  $signals{$cell_ref}[1];
>
>                             $renderer->signal_connect (
> $signals{$cell_ref}[0] =>  \&$coderef, $tree  );
>                     }
>
>
>                 if ($pos == 0){
>                          $col->set_cell_data_func($renderer, sub{
> process_combo(@_); });
>                 }
>                 $pos++;
>         }
>
>
>         my $liste = Gtk2::ListStore->new(@listedef);
>
>
>         #fill it with arbitry data
>
>           foreach (0..3){
>
>                 $pos = 0;
>                 my @model_row;
>
>
>                 # $tree->append_column($col++);
>
>                 #my $iter = $tree->append(undef);
>                 #$tree_store->set ($iter,MODEL_FIRST_COLUMN, "Parent
> $parent_nr");
>
>                 foreach my $field (@fields) {
>
>
>
>
>                         if ($pos == 0) {
>                                  push @model_row, $liste->append, $pos,
>  $_;
>                         } else {
>
>
>                                 push @model_row,  $pos, $field . " ". $_;
>                         }
>                         $pos++;
>                 }
>
>                 $liste->set(@model_row);
>         }
>         $liste->signal_connect( "row-changed" => sub { changed(@_) } );
>
>         $tree->set_model($liste);
>
>
> $vbox->pack_start($tree,TRUE,TRUE,0);
> $vbox->show_all();
> return $vbox;
> }
>
> sub cell_edited {
>   my ($cell, $path_string, $new_text, $tree) = @_;
>   print "cell_edited\n";
>   # return unless ($tree);
>  my $model = $tree->get_model;
>   my $path = Gtk2::TreePath->new_from_string ($path_string);
>   #my $model = $tree->get_model;
>    my $col = $cell->{column};
>
>   my $iter = $model->get_iter($path);
>
>   $model->set_value ($iter, $col, $new_text);
>
> }
>
> sub changed {
>         my ( $liststore, $treepath, $iter ) = @_;
>
>  print "changed\n";
>
> }
>
>
> sub setup_combo {
>          my ($column_no, $fieldname, $renderer ) = @_;
>
>         print "set_upcombo\n";
>
>         my @combo_key = keys %combo;
>         my @cols = ("key", "values");
>
>     my @liste_def;
>
>      my $pos = 0;
>     foreach my $name (@cols){
>              if ($pos++ == 0) {
>
>                      push @liste_def, "Glib::Int";
>                      # push @liste_def, "Glib::String";
>             } else {
>                     push @liste_def, "Glib::String";
>             }
>
>     }
>
>     my $model = Gtk2::ListStore->new( @liste_def );
>
>     foreach  my $key ( @combo_key ) {
>
>         my @model_row;
>
>         push @model_row, $model->append;
>         $pos = 0 ;
>         foreach my $name ( @cols) {
>
>             push @model_row, $pos, ($pos == 0 ? $key : $combo{$key});
>             $pos++;
>         }
>         $model->set( @model_row );
>
>     }
>
>          $renderer->set(
>                     editable        => TRUE,
>                     text_column     => 1,
>                      has_entry       => FALSE,
>                      model => $model
>               );
>
>  }
>  #combo -> tree
>  sub combo_changed_todel {
>         my ($cell,  $new_text, $iter, $tree) = @_;
>         # return unless ($tree);
>   print Dumper($new_text);
>         my $model = $tree->get_model;
>          print("combo_edited " . $new_text . "\n");
>                                         #       $cell->get("model");
>         $model->set ($iter, $cell->{column}, $new_text); }
>
>  sub combo_edited_todel {
>         my  ($renderer, $path_string, $new_text, $tree) = @_;
>         # return unless ($tree);
>         my $model = $tree->get_model;
>          print("combo_edited " . $new_text . "\n");
>                                         #       $cell->get("model");
> #       $model->set ($iter, $cell->{column}, $new_text);
>         my $path = Gtk2::TreePath->new_from_string( $path_string );
>          my $iter = $model->get_iter ( $path );
>                 # $combo_model->set ( $combo_iter,0, $new_text );
>         $model->set($iter,  $renderer->{column}, $new_text); }
>
>  sub combo_edited {
>          my ($renderer, $path_string, $new_text, $tree) = @_;
>         my $combo_model;
>
>         #  return unless ($renderer);
>          $combo_model = $renderer->get("model");
>        print("combo_edited : " . $new_text. "\n");
>         print Dumper($path_string);
>        my $combo_iter = $combo_model->get_iter_first;
>        #
>        # my $combo_iter = $combo_model->get_active_iter;
>         my $found_match = FALSE;
>
>         while ( $combo_iter ) {
>                 # $self->{log}->debug("combo_edited  testing: ".
>  $combo_model->get( $combo_iter, 1 ));
>             if ( $combo_model->get( $combo_iter, 1 ) eq $new_text ) {
>                 $found_match = TRUE;
>                 $new_text = $combo_model->get( $combo_iter, 0 );
>                 print("combo_edited  found: " . $new_text. "\n");
>                 last;
>             }
>
>             $combo_iter = $combo_model->iter_next( $combo_iter );
>
>         }
>
>
>
> #if (  $found_match ) {
>         if ($combo_iter){
>                   my $path = Gtk2::TreePath->new_from_string( $path_string
> );
>                     my $model = $tree->get_model;
>                     my $iter = $model->get_iter ( $path );
>                 # $combo_model->set ( $combo_iter,0, $new_text );
>                 $model->set($iter,  $renderer->{column}, $new_text);
>         }
>
>  }
>
> # $tree -> $combo
>  sub process_combo {
>      my ($tree_column, $renderer, $model, $iter ) = @_;
>
>     # Get the ID that represents the text value to display
>     my $key_value = $model->get( $iter, $renderer->{column} );
>     # print Dumper($tree_column);
>     print("process_combo  col: " . $renderer->{column}. " val: " .
> $key_value . "\n");
>     my $combo_model = $renderer->get( "model" );
>
>     if ( $combo_model ) {
>
>         # Loop through our combo's model and find a match for the above ID
> to get our text value
>         my $combo_iter = $combo_model->get_iter_first;
>         my $found_match = FALSE;
>
>         while ( $combo_iter ) {
>
>            print "testing : ",$combo_model->get( $combo_iter, 0 ), "\n";
>                 if ( $combo_model->get( $combo_iter, 0 )  && $key_value &&
> $combo_model->get( $combo_iter, 0 ) == $key_value ) {
>                     $found_match = TRUE;
>                     print("process combo found match " .
>  $combo_model->get( $combo_iter, 0 ) . "\n");
>                     $renderer->set( text    => $combo_model->get(
> $combo_iter, 1 ) );
>                     last;
>                 }
>
>
>             $combo_iter = $combo_model->iter_next( $combo_iter );
>
>         }
>
>         # If we haven't found a match, default to displaying an empty value
>         if ( ! $found_match ) {
>             $renderer->set( text    => "" );
>         }
>
>   }
> }
>
>
> _______________________________________________
> gtk-perl-list mailing list
> gtk-perl-list@gnome.org
> https://mail.gnome.org/mailman/listinfo/gtk-perl-list
>
_______________________________________________
gtk-perl-list mailing list
gtk-perl-list@gnome.org
https://mail.gnome.org/mailman/listinfo/gtk-perl-list

Reply via email to