Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Gtk.CssProvider() how do ID based selectors work in Gtk3?

I've been fiddling with this on and off for a couple of days but just can't seem to come to grips with what the issues might be.

Essentially I'm trying to style some Gtk Widgets in Gtk3 using CSS style declarations, nothing complicated but just trying to target a specific element by its id/name. The Gtk documentation for Gtk.CssProvider() says that

#widgetname { background-color: #333333; }

should work as a valid selector for a widget with its name set to "widgetname" but I just can't seem to make it work. I thought originally that it was the CSS not loading but I can target a top-level widget like so:

GtkWindow { background-color: #333; }

and it will apply the style to the window and I can see the background color has changed. I've tried using the name as an ID for a couple of different types of widgets (GtkEventBox, GtkTextView, GtkStatusBar, GtkBox) and the ID based selector just doesn't seem to work.

Here's a shortened snippet of how I'm loading the css:

css = Gtk.CssProvider()

# css.load_from_file(file)
css.load_from_data('''

GtkWindow {
    background-color: #333;
}

GtkEventBox {
    background-color: #333;
}

#statusbarwrap, #textview_event_wrap, #box1 {
     background-color: #333;
}

''')

style_context = self.get_style_context()
style_context.add_provider(
    css,
    Gtk.STYLE_PROVIDER_PRIORITY_APPLICATION)

Here is the docs for GtkCssProvider https://developer.gnome.org/gtk3/3.7/GtkCssProvider.html

Example 24 on that page (just scroll down a page or two) shows that the #ID selector is valid and I'm setting the name for the widgets in Glade.

Any help would be greatly appreciated.

like image 736
jduren Avatar asked May 24 '13 17:05

jduren


2 Answers

We can use 'gtk_widget_set_name()' to give this widget a name(ID).

win = Gtk.Window()
win.set_name('main_window')

then '#main_window' can be used as the ID selector in CSS3:

#main_window {
  background-color: ...
}

If you open a glade file using a text editor, you can find out that, the name of widget is actually taged as id, like this:

<object class="GtkWindow" id="window1">

Note that, the name of a widget should not contain special characters like *, #, or >, which are part of CSS syntax.

like image 97
LiuLang Avatar answered Sep 25 '22 22:09

LiuLang


The following is a complete example, which I'm posting here to clarify the confusion between names and IDs in Gtk3+CSS:

german.py:

# coding: utf-8
from gi.repository import Gtk, Gdk
import time

builder = Gtk.Builder()
builder.add_from_file("german.glade")
builder.connect_signals({"closeApplication": Gtk.main_quit})

screen = Gdk.Screen.get_default()

css_provider = Gtk.CssProvider()
css_provider.load_from_path('german.css')

context = Gtk.StyleContext()
context.add_provider_for_screen(screen, css_provider,
  Gtk.STYLE_PROVIDER_PRIORITY_USER)

window = builder.get_object("applicationwindow1")
window.show_all()

Gtk.main()

german.css:

#blackBox {
  background-color: black;
}
#redBox {
  background-color: red;
}
.goldBox {
  background-color: gold;
}

german.glade:

<?xml version="1.0" encoding="UTF-8"?>
<!-- Generated with glade 3.16.1 -->
<interface>
  <requires lib="gtk+" version="3.0"/>
  <object class="GtkApplicationWindow" id="applicationwindow1">
    <property name="can_focus">False</property>
    <signal name="delete-event" handler="closeApplication" swapped="no"/>
    <child>
      <object class="GtkBox" id="box1">
        <property name="visible">True</property>
        <property name="can_focus">False</property>
        <property name="orientation">vertical</property>
        <child>
          <object class="GtkEventBox" id="blackBox">
            <property name="visible">True</property>
            <property name="can_focus">False</property>
            <child>
              <placeholder/>
            </child>
          </object>
          <packing>
            <property name="expand">True</property>
            <property name="fill">True</property>
            <property name="position">0</property>
          </packing>
        </child>
        <child>
          <object class="GtkEventBox" id="eventbox2">
            <property name="name">redBox</property>
            <property name="visible">True</property>
            <property name="can_focus">False</property>
            <child>
              <placeholder/>
            </child>
          </object>
          <packing>
            <property name="expand">True</property>
            <property name="fill">True</property>
            <property name="position">1</property>
          </packing>
        </child>
        <child>
          <object class="GtkEventBox" id="eventbox3">
            <property name="visible">True</property>
            <property name="can_focus">False</property>
            <child>
              <placeholder/>
            </child>
            <style>
              <class name="goldBox"/>
            </style>
          </object>
          <packing>
            <property name="expand">True</property>
            <property name="fill">True</property>
            <property name="position">2</property>
          </packing>
        </child>
      </object>
    </child>
  </object>
</interface>

Result:

Three boxes aligned vertically, like the flag of Germany. Except that the first box is NOT black, because #name refers to an object with a matching "name" property, not to an object with that id.

It took me a while to figure it out. I'm new with Gtk3 myself...

like image 22
Locoluis Avatar answered Sep 25 '22 22:09

Locoluis