Re: Help with Gtk2::CellRendererCombo



Woah sorry I missed your reply. Now I'm even less sure of what you're trying to do :/

If you're just after getting the ID that corresponds with your text value in the combo, then $model->get( $iter, $column_no ) should give you that value ( with $column_no being the numbered position in the model ).

But then you ask about adjusting the value, based on other columns. I didn't quite understand what you're asking. Please explain with an example ...

Also, as you're using Gtk2::Ex::Datasheet::DBI, have a look at 'dynamic combo' support - it may do what you want. The idea is that you can tell it 'the values in this combo depend on the value selected in another column'. It automatically refreshes the list when the column it depends on changes. It sounds like what you want. I can point you to exactly how it does it if you can't find it.

Dan


On Wed, Feb 12, 2014 at 12:06 AM, RAPPAZ Francois <francois rappaz unifr ch> wrote:

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




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