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 dk 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 rappaz 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