Re: Gtk3 and subclassing



On Fri, 30 Nov 2018 at 19:09, Jeff via gtk-perl-list <gtk-perl-list gnome org> wrote:
Whilst working up a smallest working example for another bug, I've
discovered that I cannot get subclassing working when the main package
is in the same file as the module.

Below is the Gtk2 subclassing example from Muppet which I have trivially
converted to Gtk3.


Your GTK 3 port is wrong.
 
I get the following error messages:

Odd number of elements in anonymous hash at
/usr/lib/x86_64-linux-gnu/perl5/5.28/Glib/Object/Introspection.pm line 267.
*** unhandled exception in callback:
***   Can't locate object method "get_colormap" via package
"Gtk3::EventBox" at ../gtk3-subclass.pl line 93.
***  ignoring at
/usr/lib/x86_64-linux-gnu/perl5/5.28/Glib/Object/Introspection.pm line 67.

What is going on?

You're calling the "get_colormap()" method on a GtkEventBox, which does not have a "get_colormap()" method—and neither do all its parent classes.

In GTK 2.x, there is a `gtk_widget_get_colormap()` method, but it was deprecated during the GTK 2.x API series, and thus removed once GTK 3.0 was released.
 
sub set_color {
        my $self = shift;
        my %params = @_;
        my $color = Gtk3::Gdk::Color->new ($params{red},
                                           $params{green},
                                           $params{blue});
        $self->{colorbox}->get_colormap->alloc_color ($color, 0, 1);
        $self->{colorbox}->modify_bg ('normal', $color);
        $self->{colorbox}->modify_bg ('active', $color);
        $self->{colorbox}->modify_bg ('prelight', $color);
        $self->{red} = $params{red};
        $self->{green} = $params{green};
        $self->{blue} = $params{blue};
        # emit the color-changed signal.  note again that the signal
        # name treats - and _ as equivalent.
        $self->signal_emit ('color-changed');
}

Creating a colormap, allocating a color, and calling `modify_bg()` was something used in GTK 2.x (and even there, it was questionable, as it broke themes).

In GTK 3.x you're supposed load a CSS fragment, defining the background-color CSS property for a specific class, e.g.

    .foo { background-color: red; }
    .foo:active { background-color: green; }
    .foo:hover { background-color: blue; }

You load this using a GtkCSSProvider associated to the GdkScreen, and loaded when you create your application instance.

If you're trying to set the color programmatically, overriding all user theming, you can generate a CSS fragment programmatically and associate it to the widget itself, instead of the global GdkScreen; or you can override the GtkWidget::draw signal, and render the color yourself using Cairo. Doing either of those is less than great, but it respects the original example's intent.

Ciao,
 Emmanuele.

--


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