I'm still struggling with the cellRendererCombo. The combo has 2 columns (say id, name) one which holds a numeric value not displayed (id) and, the visible column which holds a text (name).
The suggestion at http://stackoverflow.com/questions/3534665/gtk-trouble-modifying-treeview-model-on-cellrenderercombo-changed-signal led me to the code below where I get a ref of the underlaying Gtk2::Combo with the sub on editing-started event. That ref can be used to get an active iterator in the sub fired with the edited event and I can get the value selected with the combo. There are 2 problems at least: - I need a hash of the whole combo content to diplay the name in the combo using the id, but someway these should be already in the model - I would prefer using the CellRendercombo model to display the name rather then calling a sub with set_cell_data_func Can anyone show me how to change this ? Thanks, 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(@_)}], ); #'Gtk2::CellRendererCombo' => ['changed', sub { combo_changed(@_)}], 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(); my $maincombo; #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, $tree); } #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){ $renderer->signal_connect ( "editing-started" => \&start_editable ); #$renderer->signal_connect ( "edited" => \&combo_edited, $tree ); $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 combo_changed_notused { my ($combo, $path_string, $new_iter, $tree) = @_; #my $path = Gtk2::TreePath->new_from_string( $path_string ); # my $iter = $combo->get_iter ( $path ); #my $new_text = $combo->get( $new_iter, 0 ); my $event = Gtk2::Gdk::Event->new('focus-change'); $event->window ($tree->get_bin_window); $event->send_event(TRUE); $event->in(FALSE); $maincombo->signal_emit('focus-out-event', $event); # print "combo_changed: ", $new_iter, "\n"; # $combo_model->set ( $combo_iter,0, $new_text ); #$combo->set($iter, $renderer->{column}, $new_text); } sub start_editable { my ($cell, $editable, $path) = @_; print "start_editable\n"; # print Dumper($editable); $maincombo = $editable; } sub setup_combo { my ($column_no, $fieldname, $renderer, $tree ) = @_; 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 ); # combo_edited($renderer, $combo{$key}, $combo{$key}, $tree); } $renderer->set( editable => TRUE, text_column => 1, has_entry => FALSE, model => $model, ); } sub combo_edited { my ($renderer, $path_string, $new_text, $tree) = @_; # return unless ($tree); # treeViewModel[path][columnNumber] = newText 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 $citer = $maincombo->get_active_iter; my $cmodel = $maincombo->get_model; my $value = $cmodel->get($citer, 0); print("combo_edited value :" . $value . "\n"); my $iter = $model->get_iter ( $path ); # $combo_model->set ( $combo_iter,0, $new_text ); $model->set($iter, $renderer->{column}, $new_text); } sub process_combo { my ($tree_column, $renderer, $model, $iter ) = @_; my $id = $model->get( $iter, 0 ); $renderer->set( text => $combo{$id} ) if (exists $combo{$id}); } _______________________________________________ gtk-perl-list mailing list gtk-perl-list@gnome.org https://mail.gnome.org/mailman/listinfo/gtk-perl-list