I've been unable to figure out what I'm doing wrong. I'm sure it's something simple but escaping me. Even in the following example I'm unable to get this working. I cannot seem to apply a CSS style to a GtkEntry widget in a single GtkWindow. I'm simply trying to turn the background of the entry box red.
Everything I've reviewed and examples I've seen all look like the below and nobody else seems to be stumped.
Here is my Python:
import gi
gi.require_version('Gtk', '3.0')
gi.require_version('Gdk', '3.0')
from gi.repository import Gtk
from gi.repository import Gdk
builder = Gtk.Builder()
builder.add_from_file("entry.glade")
window = builder.get_object('window1')
window.connect('destroy', Gtk.main_quit)
css = "#red { background-image: linear-gradient(red); }"
provider = Gtk.CssProvider()
provider.load_from_data(css)
Gtk.StyleContext().add_provider_for_screen(Gdk.Screen.get_default(), provider, Gtk.STYLE_PROVIDER_PRIORITY_APPLICATION)
entry = builder.get_object('entry1')
entry_style_context = entry.get_style_context()
entry_style_context.add_class("red")
window.show_all()
Gtk.main()
And here is the Glade XML:
<?xml version="1.0" encoding="UTF-8"?>
<interface>
<requires lib="gtk+" version="3.0"/>
<!-- interface-naming-policy project-wide -->
<object class="GtkWindow" id="window1">
<property name="can_focus">False</property>
<child>
<object class="GtkVBox" id="vbox1">
<property name="visible">True</property>
<property name="can_focus">False</property>
<child>
<object class="GtkEntry" id="entry1">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="invisible_char">●</property>
<property name="primary_icon_activatable">False</property>
<property name="secondary_icon_activatable">False</property>
<property name="primary_icon_sensitive">True</property>
<property name="secondary_icon_sensitive">True</property>
</object>
<packing>
<property name="expand">True</property>
<property name="fill">True</property>
<property name="position">0</property>
</packing>
</child>
</object>
</child>
</object>
</interface>
If I set the CSS to .entry { background-image: linear-gradient(red); }
it works, but then all GtkEntry boxes would be red (which I don't want).
What in the world am I missing?
Question: Apply
CSS
to aGtkEntry
Widget
As ptomato in his answer describes, you can't use css = "#red ...
if you don't define a name
for your widget.
Define a widgets name
, using either:
glade
file: <property name="name">red</property>
entry = builder.get_object('entry1')
entry.set_name('red')
Method 1: Using a widgets name,
css = b"#entry ...
:
name
in the glade
file to entry
<child>
<object class="GtkEntry" id="entry1">
<property name="name">entry</property>
Define your CSS
using the widgets name entry
:
css = b"#entry {background-image: linear-gradient(red, orange); color: white;}"
Working example, using a widgets name:
class App:
def __init__(self):
super().__init__()
builder = Gtk.Builder()
builder.add_from_file("entry.glade")
window = builder.get_object('window1')
window.connect('destroy', Gtk.main_quit)
css = b"#entry {background-image: linear-gradient(red, orange);}"
provider = Gtk.CssProvider()
provider.load_from_data(css)
Gtk.StyleContext()\
.add_provider_for_screen(Gdk.Screen.get_default(),
provider,
Gtk.STYLE_PROVIDER_PRIORITY_APPLICATION)
window.show_all()
if __name__ == "__main__":
main = App()
Gtk.main()
Method 2: Using a widgets style class,
css = b".entry.red ...
:
Gtk.Widget.get_style_context, Gtk.StyleContext.add_class
CSS
using nested style class .entry
, .red
, .blue
: css = b"""
.entry {color: white;}
.entry.red {background-image: linear-gradient(red, orange);}
.entry.blue {background-image: linear-gradient(blue, lightblue);}
entry1 = builder.get_object('entry1')
entry1.get_style_context().add_class("entry")
entry1.get_style_context().add_class("red")
# the same for `entry2`
...
Working example using a widgets style class:
class App:
def __init__(self):
super().__init__()
builder = Gtk.Builder()
builder.add_from_file("entry.glade")
window = builder.get_object('window1')
window.connect('destroy', Gtk.main_quit)
css = b"""
.entry { color: white;}
.entry.red { background-image: linear-gradient(red, orange);}
.entry.blue { background-image: linear-gradient(blue, lightblue);}
"""
provider = Gtk.CssProvider()
provider.load_from_data(css)
Gtk.StyleContext()\
.add_provider_for_screen(Gdk.Screen.get_default(),
provider,
Gtk.STYLE_PROVIDER_PRIORITY_APPLICATION)
entry1 = builder.get_object('entry1')
entry1.set_text('TEST')
entry1.get_style_context().add_class("entry")
entry1.get_style_context().add_class("red")
entry2 = builder.get_object('entry2')
entry2.set_text('TEST')
entry2.get_style_context().add_class("entry")
entry2.get_style_context().add_class("blue")
window.show_all()
if __name__ == "__main__":
main = App()
Gtk.main()
Tested with Python: 3.5 - gi.__version__: 3.22.0 - Glade 3.20.0