hanspr has asked for the wisdom of the Perl Monks concerning the following question:

Dear Monks,

Gtk3::SimpleList

Allows to assign 1 column to 1 cell type.
my $slist = Gtk3::SimpleList->new ( 'Text Field' => 'text', 'Markup Field' => 'markup', 'Int Field' => 'int', 'Double Field' => 'double', 'Bool Field' => 'bool', 'Scalar Field' => 'scalar', 'Pixbuf Field' => 'pixbuf', );

And there is a method : add_column_type, that lets you create your own column type.

I need to create a type that allows me to display 2 different cell types in the same column
A pixbuf cell and a text cell, both in the same column.

Is it possible?

The 2 example shown in the module, do not give me a clue if this is possible or how can be implement it.

Example from module

# just displays the value in a scalar as # Perl would convert it to a string Gtk3::SimpleList->add_column_type( 'a_scalar', type => 'Glib::Scalar', renderer => 'Gtk3::CellRendererText', attr => sub { my ($treecol, $cell, $model, $iter, $col_num) = @_; my $info = $model->get ($iter, $col_num); $cell->set (text => $info); } ); # sums up the values in an array ref and displays # that in a text renderer Gtk3::SimpleList->add_column_type( 'sum_of_array', type => 'Glib::Scalar', renderer => 'Gtk3::CellRendererText', attr => sub { my ($treecol, $cell, $model, $iter, $col_num) = @_; my $sum = 0; my $info = $model->get ($iter, $col_num); foreach (@$info) { $sum += $_; } $cell->set (text => $sum); } );


If someone has reference to an example of how to accomplish this with Gtk3::SimpleList, would be greatly appreciated.

Replies are listed 'Best First'.
Re: Gtk3::SimpleList create personal type with 2 cells in same column
by Anonymous Monk on Jan 09, 2020 at 00:20 UTC
      Thanks for the information, I documented the solution as a new comment on the original question.
Re: Gtk3::SimpleList create personal type with 2 cells in same column
by hanspr (Sexton) on Jan 31, 2020 at 06:12 UTC
    Documenting for any other interested on this.

    Is the only way I managed to do make it work.

    The concept is to create 3 columns

    The first column has to be a user defined column
    The 2nd and the 3rd hold the text and icon we want to join
    We hide the 2nd and 3rd columns

    We create our custom column that joins the 2nd and 3rd Columns

    Tried to use Gtk3::CellRenderer as the renderer for the user defined render but it fails.
    So had to declare a Textrender, and then clear the column attributes and recreate the attributes again.


    Gtk3::SimpleList->add_column_type('image_text', type => 'Glib::Scalar', renderer => 'Gtk3::CellRendererText', attr => sub { my ($treecol, $cell, $model, $iter, $col_num) = @_; my $pixrd = Gtk3::CellRendererPixbuf->new(); my $txtrd = Gtk3::CellRendererText->new(); $treecol->clear(); $treecol->pack_start($pixrd,0); $treecol->pack_start($txtrd,1); $treecol->add_attribute($pixrd,'pixbuf',1); $treecol->add_attribute($txtrd,'markup',2); } ); # Create your model my $slist = Gtk3::SimpleList->new ( 'Text Field' => 'text_icon', 'text' => 'markup', 'icon' => 'pixbuf', ); # Hide text and icon my @col = $slist->get_columns; $col[1]->set_visible(0); $col[2]->set_visible(0);


Re: Gtk3::SimpleList create personal type with 2 cells in same column
by hanspr (Sexton) on Feb 01, 2020 at 16:17 UTC
    Update on this.

    The previous solution generates gtk warnings, it works, but a friend found the right way to build this column correctly.

    # Defines a special column type that does not use a standard rende +rer # The renderer is built by function 'column_builder' # The renderer will assume the first attribute of the model is def +ining the icon to show # and the second attribute contains the markup text to display $class->add_column_type('image_text', type => 'Glib::Scalar', renderer => undef, column_builder => sub { my $pixrd = Gtk3::CellRendererPixbuf->new(); my $txtrd = Gtk3::CellRendererText->new(); my $column = Gtk3::TreeViewColumn->new(); $column->pack_start($pixrd, 0); $column->pack_start($txtrd, 1); $column->add_attribute($pixrd, 'pixbuf', 0); $column->add_attribute($txtrd, 'markup', 1); return $column; } ); # Build the columns list for this new tree # according to the definition of column types my @column_info = (); for (my $i = 0; $i < @_ ; $i+=2) { my $typekey = $_[$i+1]; croak "expecting pairs of title=>type" unless $typekey; croak "unknown column type $typekey, use one of " . join(", ", keys %column_types) unless exists $column_types{$typekey}; my $type = $column_types{$typekey}{type}; if (not defined $type) { $type = 'Glib::String'; carp "column type $typekey has no type field; did you" . " create a custom column type incorrectly?\n" . "limping along with $type"; } push @column_info, { title => $_[$i], type => $type, rtype => $column_types{$_[$i+1]}{renderer}, attr => $column_types{$_[$i+1]}{attr}, column_builder => $column_types{$_[$i+1]}{column_builder}, }; } ## Create the store my $model = Gtk3::TreeStore->new (map {$_->{type}} @column_info); for (my $i = 0; $i < @column_info ; $i++) { if (!defined($column_info[$i]{rtype}) && defined($column_info[ +$i]{column_builder}) && ('CODE' eq ref $column_info[$i]{column_builde +r})) { # A column builder has been defined $view->append_column($column_info[$i]{column_builder}()); } elsif ('CODE' eq ref $column_info[$i]{attr}) { $view->insert_column_with_data_func (-1, $column_info[$i]{title}, $column_info[$i]{rtype}->new, $column_info[$i]{attr}, $i); } elsif ('hidden' eq $column_info[$i]{attr}) { # skip hidden column } else { my $column = Gtk3::TreeViewColumn->new_with_attributes ( $column_info[$i]{title}, $column_info[$i]{rtype}->new, $column_info[$i]{attr} => $i, ); $view->append_column ($column); if ($column_info[$i]{attr} eq 'active') { # make boolean columns respond to editing. my $r = $column->get_cells; $r->set (activatable => 1); $r->signal_connect (toggled => sub { my ($renderer, $row, $col) = @_; my $path = Gtk3::TreePath->new_from_string ($row); my $iter = $model->get_iter ($path); my $val = $model->get ($iter, $col); $model->set ($iter, $col, !$val); }, $i); } elsif ($column_info[$i]{attr} eq 'text') { # attach a decent 'edited' callback to any # columns using a text renderer. we do NOT # turn on editing by default. my $r = $column->get_cells; $r->{column} = $i; $r->signal_connect (edited => \&text_cell_edited, $model); } } }