RE: Help with Gtk2::CellRendererCombo



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

 



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]