What does set_css_name do?

According to the documentation, set_css_name “Sets the name to be used for CSS matching of widgets”. Consider the following program:

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

def css_load_from_data(css_data):
    screen = Gdk.Screen.get_default()
    css_provider = Gtk.CssProvider()
    style_context = Gtk.StyleContext()
    style_context.add_provider_for_screen(screen, css_provider,
            Gtk.STYLE_PROVIDER_PRIORITY_APPLICATION)
    css_provider.load_from_data(css_data.encode('utf-8'))

css_data = """
    #cssname {
        background-color: red;
    }"""

loop = GLib.MainLoop()
window = Gtk.Window()
window.show()
window.set_css_name('cssname')
#window.set_name('cssname')
css_load_from_data(css_data)
window.connect_after('destroy', lambda obj: loop.quit())
loop.run()

When I use window.set_css_name, the background color remains black. If I use window.set_name instead, I get red. The documentation for set_css_name leads me to expect that using it would produce the same red background. Am I misinterpreting the documentation? What is the actual application of set_css_name if not this?

Yes.

The CSS name is the name of the element in the UI graph, not the widget identifier. So, a GtkButton has a CSS name of button, a GtkWindow has a CSS name of window, and so on, and so forth.

You should set the CSS name if you’re creating a widget class, and you don’t want your class to inherit the CSS name of its parent type.

1 Like

I am still missing something. It doesn’t matter whether I put #, ., or nothing in front of cssname, I still do not get a red background. With this css_data:

css_data = """
    cssname {
        background-color: red;
    }
    window {
        background-color: blue;
    }"""

I get blue, so it seems as if the name has not changed.

You can only use it when implementing a class. That is, it sets the CSS name of the type, not for one particular instance.

2 Likes

Ah. So this works:

def css_load_from_data(css_data):
    screen = Gdk.Screen.get_default()
    css_provider = Gtk.CssProvider()
    style_context = Gtk.StyleContext()
    style_context.add_provider_for_screen(screen, css_provider,
            Gtk.STYLE_PROVIDER_PRIORITY_APPLICATION)
    css_provider.load_from_data(css_data.encode('utf-8'))

css_data = """
    cssname {
        background-color: red;
    }"""

class RedWindow(Gtk.Window):
    __gtype_name__ = 'RedWindow'

    Gtk.Window.set_css_name('cssname')

    css_load_from_data(css_data)

    def __init__(self):
        super().__init__()
        self.show()

redwindow = RedWindow()
Gtk.main()

Thanks for the help.

Better:

class RedWindow(Gtk.Window):
    def __new__(cls, *args, **kwargs):
        cls.set_css_name('cssname')
        return super().__new__(cls)

This way, the css name of Window is still window but the css name of the subclass RedWindow is cssname.

This will call RedWindow.set_css_name('cssname') every time you create an instance of RedWindow. To do it once, after defining the class, do

class RedWindow(Gtk.Window):
    ...

RedWindow.set_css_name('cssname')

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.