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