Hi Daniel Thanks for replying With
$column->set_cell_data_func($renderer, sub{ process_combo(@_); }); ... Sub process_combo { my ($tree_column, $renderer, $model, $iter ) = @_; ... } $model and $iter refer to the data grid (the tree) not the combo in the cell. How can I adjust the combo when the value in the grid (coming from a database) changes without looping in the whole combo ? By the way, I know, and I use your modules ! François From: Daniel Kasak [mailto:d.j.kasak...@gmail.com] Sent: dimanche, 9. février 2014 06:41 To: RAPPAZ Francois Cc: gtk-perl-list@gnome.org Subject: Re: Help with Gtk2::CellRendererCombo 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<mailto: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<mailto: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