Help with Gtk2::CellRendererCombo
- From: RAPPAZ Francois <francois rappaz unifr ch>
- To: "gtk-perl-list gnome org" <gtk-perl-list gnome org>
- Subject: Help with Gtk2::CellRendererCombo
- Date: Fri, 7 Feb 2014 15:09:17 +0000
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 => "" );
}
}
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]