Skip to main content

Jumping off the greyscale

Pimp GUI using Cascading Style Sheets

CSS

GTK+ objects' layouts can be altered by using CSS. In my humble opinion the usage should not be exaggerated and the main part of the layout should be left to be managed by the theme. Links:

Glade

/images/07_css.thumbnail.png

CSS layout instructions are set in the source code. This example shows the usage of CSS in levelbars so 4 of them are created with Glade.

Python

CSS

The pattern for layout instructions is

widget [element] {
  font...
  color...
  background...
  ...
}

that are stored in a string variable loaded by the Gtk.CssProvider() class.

Levelbar

Levelbar values can be displayed in different colours depending on the defined value range (see article "Bars"), p.e. to visualize a critical battery status. The predefined offset markers are:

  • low (<=.25)

  • high (<=.75)

  • full (bis 1)

The values can be retrieved by the get_offset_value function or created/changed with the add_offset_value function.

In the example the 4th levelbar has an additional offset marker between high and full that's why a value of 0.8 is not visualized as full like it is in the 3rd levelbar.

self.bar.add_offset_value("alert",.9)

Listings

Glade

07_css.glade (Source)

<?xml version="1.0" encoding="UTF-8"?>
<!-- Generated with glade 3.20.0 -->
<interface>
  <requires lib="gtk+" version="3.20"/>
  <object class="GtkWindow" id="window">
    <property name="can_focus">False</property>
    <property name="default_width">400</property>
    <property name="default_height">150</property>
    <signal name="destroy" handler="on_window_destroy" swapped="no"/>
    <child>
      <object class="GtkBox">
        <property name="visible">True</property>
        <property name="can_focus">False</property>
        <property name="orientation">vertical</property>
        <property name="homogeneous">True</property>
        <child>
          <object class="GtkLevelBar" id="lev1">
            <property name="visible">True</property>
            <property name="can_focus">False</property>
            <property name="margin_top">5</property>
            <property name="margin_bottom">5</property>
            <property name="value">0.20000000000000001</property>
          </object>
          <packing>
            <property name="expand">False</property>
            <property name="fill">True</property>
            <property name="position">0</property>
          </packing>
        </child>
        <child>
          <object class="GtkLevelBar" id="lev2">
            <property name="visible">True</property>
            <property name="can_focus">False</property>
            <property name="margin_top">5</property>
            <property name="margin_bottom">5</property>
            <property name="value">0.5</property>
          </object>
          <packing>
            <property name="expand">False</property>
            <property name="fill">True</property>
            <property name="position">1</property>
          </packing>
        </child>
        <child>
          <object class="GtkLevelBar" id="lev3">
            <property name="visible">True</property>
            <property name="can_focus">False</property>
            <property name="margin_top">5</property>
            <property name="margin_bottom">5</property>
            <property name="value">0.80000000000000004</property>
          </object>
          <packing>
            <property name="expand">False</property>
            <property name="fill">True</property>
            <property name="position">2</property>
          </packing>
        </child>
        <child>
          <object class="GtkLevelBar" id="lev4">
            <property name="visible">True</property>
            <property name="can_focus">False</property>
            <property name="margin_top">5</property>
            <property name="margin_bottom">5</property>
            <property name="value">0.80000000000000004</property>
          </object>
          <packing>
            <property name="expand">False</property>
            <property name="fill">True</property>
            <property name="position">3</property>
          </packing>
        </child>
      </object>
    </child>
    <child>
      <placeholder/>
    </child>
  </object>
</interface>

Python

07_css.py (Source)

#!/usr/bin/python
# -*- coding: utf-8 -*-

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


class Handler:

    def on_window_destroy(self, *args):
        Gtk.main_quit()


class Example:

    def __init__(self):

        self.builder = Gtk.Builder()
        self.builder.add_from_file("07_css.glade")
        self.builder.connect_signals(Handler())

        css = b"""

levelbar trough block.filled.low {
    background-color: green;
}

levelbar trough block.filled.high {
    background-color: yellow;
}

levelbar trough block.filled.alert {
    background-color: orange;
}

levelbar trough block.filled.full {
    background-color: red;
}
"""
        #load css stylesheet
        style_provider = Gtk.CssProvider()
        style_provider.load_from_data(css)

        Gtk.StyleContext.add_provider_for_screen(
            Gdk.Screen.get_default(),
            style_provider,
            Gtk.STYLE_PROVIDER_PRIORITY_APPLICATION
        )

        self.bar = self.builder.get_object("lev4")
        self.bar.add_offset_value("alert", .9)

        print("low:  ", self.bar.get_offset_value("low"))
        print("high: ", self.bar.get_offset_value("high"))
        print("alert:", self.bar.get_offset_value("alert"))
        print("full: ", self.bar.get_offset_value("full"))

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

    def main(self):
        Gtk.main()


x = Example()
x.main()

Comments

Comments powered by Disqus