How to get the background color of a widget in GTK and Python?
Asked Answered
C

3

11

I want to get the normal background color of a widget (a GtkHeaderBar, in this case). I'm currently using

style = self.get_titlebar().get_style_context()

to get the style, and

color = style.get_property("background-color", Gtk.StateFlags.NORMAL)

to get the background color associated to that style.

However it returns a Gkd.RGBA object with the following properties:

Gdk.RGBA(red=0.000000, green=0.000000, blue=0.000000, alpha=0.000000)

But if I open GTK Inspector, select the HeaderBar, and goes to the style properties, it shows

background-color | rgb(57,63,63) | gtk-contained-dark.css:1568.29

What do I have to do to get these same values?

Edit:

I am experimenting with the GtkStyleContext.render_background(), but I'm having no success:

surfc = Cairo.ImageSurface (Cairo.FORMAT_ARGB32, 10, 10)
contx = Cairo.Context(surfc)
style = self.get_titlebar().get_style_context()
backg = Gtk.render_background(style, contx, 10, 10, 10, 10)
surfc.write_to_png("test.png")

The resulting file test.png is a rgba(0, 0, 0, 0) image.

Chervonets answered 25/7, 2015 at 15:25 Comment(0)
O
5

You should have a look at modifying the background-color with css. There is a very good documentation of it. It can be used with python with

css_provider = Gtk.CssProvider()
css_provider.load_from_path('application.css')
Gtk.StyleContext.add_provider_for_screen(
    Gdk.Screen.get_default(),
    css_provider,
    Gtk.STYLE_PROVIDER_PRIORITY_APPLICATION
)

and a css file like:

GtkHeaderbar {
    background-color:@theme_bg_color;
}

EDIT: As you commented you do not want to modify the background color but retrieve the value of it. You can do widget.get_style_context().get_background_color() and it will return something like Gdk.RGBA(red=0.913725, green=0.913725, blue=0.913725, alpha=1.000000).

However, you should note that get_background_color() is deprecated since there is not one background color. Some widget use a gradient as a background so it is not the best solution to use this method. See the documentation for reference.

Onetime answered 25/7, 2015 at 22:20 Comment(4)
Sorry, I don't want to modify the background-color with css. I wanna get the current background-color.Chervonets
Yeap, I'm aware of get_background_color(). However it always returns rgba(0, 0, 0, 0). Probably because the widget is using a gradient...Chervonets
-1, this doesn't answer the question, and get_background_color() is deprecated as well as not supporting backgrounds other than plain colors, which is not, if not infrequently, the case. Most buttons, bars and even window backgrounds show gradient features nowadays.Rory
How incredibly hard it was to stumble across this. Now I can finally paint my widgets in a different theme color. thanks.Daune
S
2

You were on the right track, but there is an issue with new recommended way to get colors.

The recommended workaround is to fall back to the deprecated get_background_color()

import gi
gi.require_version('Gtk', '3.0')
from gi.repository import Gtk
import sys

window = Gtk.Window()
context = window.get_style_context()
# this one is buggy
color1 = context.get_property("background-color", Gtk.StateFlags.NORMAL)
print(color1)
# this is the deprecated version, but it is the recommended workaround
color2 = context.get_background_color(Gtk.StateFlags.NORMAL)
print(color2)

From the python/Gtk documentation,

Note that passing a state other than the current state of self is not recommended unless the style context has been saved with Gtk.StyleContext.save()

So the current recommended way to get a widget background color is

context = widget.get_style_context()
color = context.get_background_color(widget.get_state())

Often self is a Gtk widget, and this becomes

context = self.get_style_context()
color = context.get_background_color(self.get_state())
Smallage answered 21/2, 2019 at 18:11 Comment(0)
N
1

If anyone's interested, I think the problem lies here:

backg = Gtk.render_background(style, contx, 10, 10, 10, 10)

while it should be:

backg = Gtk.render_background(style, contx, 0, 0, 10, 10)
Natation answered 31/1, 2018 at 13:14 Comment(1)
This was not the main issue (see my answer), but this is indeed why the render_background resulting image had zero size. Good catch !Smallage

© 2022 - 2024 — McMap. All rights reserved.