model for CellRendererCombo
- From: RAPPAZ Francois <francois rappaz unifr ch>
- To: "gtk-perl-list gnome org" <gtk-perl-list gnome org>
- Subject: model for CellRendererCombo
- Date: Wed, 12 Feb 2014 15:50:29 +0000
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});
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]