Re: SimpleList: connecting a signal to a CellRendererToggle

----- Original Message -----
Date: Thu, 5 Aug 2004 16:33:54 -0400 (EDT)
From: "muppet" <scott asofyet org>
To: gtk-perl-list gnome org

Subject: Re: SimpleList: connecting a signal to a CellRendererToggle

GrÃgory SCHMITT said:
Here's the deal: I have three columns of ticking boxes. When
clicking on a tick in the first column, it should untick the 2nd
column and tick the 3rd one (it's an example; in reality, the
behaviour should be à la radio button, but I would prefer to have
ticking boxes).

you can tell the renderer to draw itself like a radiobutton.

  # create the simplelist; this will create the actual cell renderer
  # that will be used.
  $simplelist = Gtk2::SimpleList->new (...);
  # now fetch the renderer you want and futz with it.
  $n = the index of the column with the toggle renderer
  my @r = $simplelist->get_column ($n)->get_cell_renderers;
  $r[0]->set (radio => TRUE); # assuming the toggle renderer is the
  only one

My idea was then to
create a column type and connect a signal to the column.

Here's the code:

                    type     => 'Glib::Boolean',
                    renderer => 'Gtk2::CellRendererToggle',
                    attr     =>
                    sub {
                         my ($column, $cell, $model, $iter, $nb_col) = @_;

                         my $renderer = $column->get_cell_renderers;
                         $renderer->set('activatable' => 1);

this is redundant --- the callback has already received a reference to
the cell renderer being operated on, in $cell!

I had just seen that a few minutes later...

                         $renderer->signal_connect(toggled => sub {

this will connect a new toggled handler to the cell *every* *time* the
treeviewcolumn calls the cell data function (which is really, really
often). that will blow up exponentially.  what you really want is to
connect this just after creating the simplelist, by the same method as
i showed above for setting the radio property.

                            my ($renderer, $row, $col) = @_;
                            my $iter = $model->iter_nth_child(undef, $row);
                            my $val = $model->get($iter, $col);

                            $model->set($iter, $col, !$val);
                            $model->set($iter, $col+1, 0);
                            $model->set($iter, $col+2, 1);

not sure you want hard-coded values here, don't you want $val and

Huh, no, hard coded values were fine.

                            print("$row - $col\n");
                            print("Valeur: " . $model->get($iter, $nb_col) . "\n");
                         }, $nb_col);

There are 2 problems with it:

- clicking on a tick box in the first column do untick and tick the
other columns, but the clicked tick box doesn't look like ticked (it
stays empty).

you've supplied an attr function to add_column_type(); this function
is used as the cell data callback, the function the column calls to
set up the cell renderer to draw a particular cell for the proper
attributes of the model. however, you never actually set the active
property of the renderer.

the cell data function is the wrong place to connect the callback, and
when you take that out, it doesn't do anything.  instead, you want the
toggle to reflect the value in the model.  thus, tell simple list that
for this column, the attribute to sync with the model is "active".

    attr => 'active',  # instead of the subroutine reference

- for an unknow reason, clicking only once outputs a lot of
information(as stated in the two print lines at the end of the
code). Worse, the last print gives me a "Valeur: 0" whereas it
should be 1 !

the "lots of information" bit is because of the extraneous
connections, as i said above.

I'm using Perl-Gtk2 1.021, Perl 5.8.3, libgtk-2.2.

wow, only 9 months old and already 1.021 seems like ancient history. 

1.043 has lots of little bugfixes that you might want, and a
guaranteed-not-to-be-broken API.  we're also planning 1.060 for gnome
2.8. please consider upgrading.  =)

try it like this:

  use strict;
  use Gtk2 -init;
  use Gtk2::SimpleList;

                    type     => 'Glib::Boolean',
                    renderer => 'Gtk2::CellRendererToggle',
                    attr     => 'active',

  my $slist = Gtk2::SimpleList->new ('one' => 'mybool',
                                     'two' => 'bool',
                                     'three' => 'bool');
  my ($renderer) = $slist->get_column (0)->get_cell_renderers;
  $renderer->set (activatable => 1);

  $renderer->signal_connect (toggled => sub {
      my ($renderer, $pathstr, $model) = @_;
      my $path = Gtk2::TreePath->new_from_string ($pathstr);
      my $iter = $model->get_iter ($path);
      my $val = $model->get($iter, 0);

      $model->set($iter, 1, !$val);
      $model->set($iter, 2, !$val);
  }, $slist->get_model);

  @{$slist->{data}} = (
      [ 0, 1, 1 ],
      [ 1, 0, 0 ],
      [ 0, 1, 1 ],
      [ 1, 0, 0 ],

  my $window = Gtk2::Window->new;
  $window->add ($slist);
  $window->signal_connect (destroy => sub {Gtk2->main_quit});

That's exactly what I wanted to do. Thank you very much, your code has been really helpful.

muppet <scott at asofyet dot org>
gtk-perl-list mailing list
gtk-perl-list gnome org
GrÃgory SCHMITT <mailto:gregory schmitt free fr>

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