Find child in Box by CSS name

I have a GtkBox called “tab” which has 3 children: tab-name (GtkLabel), tab-icon (GtkImage), and tab-close (GtkButton).

I have a reference to “tab”, but I can’t seem to find a function that can help me find tab-name within it to change its label. How can this be done?

Hi,

What do you mean exactly by “name”?
There are 3 kinds of identifiers that are used by CSS:

  • the class CSS name, like label, image, button. It’s the same for all widgets of the same type. You can get it with Gtk.WidgetClass.get_css_name. It’s hardcoded at widget class declaration, can’t be changed.
  • the widget name, shall be unique, get it with Gtk.Widget.get_name. In CSS you can refer it by prefixing a sharp symbol, like #mywidgetname.
  • the CSS classes, you can assign any number of them to any number of widgets, refer them with a dot prefix like .mycustomclass in CSS. You can check if a class is applied with Gtk.Widget.has_css_class.

Hey,

My bad, I forgot to specify that I meant the CSS name. The tab-* names I’ve mentioned are set with css_name(...).

Seems like GtkContainer has get_children, but it doesn’t exist on GtkBox.

GtkBox has GtkContainer as ancestor though. The docs say it inherits GtkContainer methods, including the get_children(), but it doesn’t seem like so:

no method named `get_children` found for struct `gtk4::Box` in the current scope

For now I kept the tab-* I needed in a struct and used them later in the code.

That’s gtk3, there is no GtkContainer anymore in gtk4.

In gtk4 for looping over children you have to Gtk.Widget.get_first_child then loop on Gtk.Widget.get_next_sibling till it returns NULL.

for (child = gtk_widget_get_first_child (widget);
     child != NULL;
     child = gtk_widget_get_next_sibling (child))
  {
    // do something with child
  }

Side note: with advanced language bindings like Python, containers are automatically iterables, so the looping is much easier:

box = Gtk.Box()
...
# add widgets to box
...
for child in box:
   ...
    if child.get_css_name() == "tab-name":
        print("found the label")

Don’t do that, please.

The CSS name is the equivalent of p or div in HTML: it’s meant to select all widgets when styling.

The widget’s name is meant as a debugging tool, as GTK does not enforce uniqueness.

If you’re traversing a widget tree to find specific widgets you’re also doing something fairly inefficient; if you need quick access to specific widgets, keep a reference to them into a state object, or, if you’re subclassing a type, keep a reference in the instance data structure.

2 Likes

If you use css_name then you shall create custom widgets and set the css_name in their *_class_init().

Here how it’s done for GtkButton : gtk_button_class_init()

1 Like