Skip to content Skip to sidebar Skip to footer

Best Way To Set Entry Background Color In Python Gtk3 And Set Back To Default

What is the best way to set background color for one entry and set it back to the default color? My script is now working but I am very sure this is not the best way. Also I still

Solution 1:

I will first address the issues you mention, as they give insight into what is going on in GTK and OP's code. The answer to the main question (and proper code for doing this) is all the way at the bottom of the answer.


  1. If I insert a text, not containing string "red" or "green" and select this text I cant see my selection because It is all white.

The reason this happens is because the background property is used, this sets all background related properties of the Entry to that color. So both that of the selection as well as the "real" background.

Then the question is what property do we use, this is a part of GTK which is poorly documented but we can find out using the GtkInspector which lets us see what style properties are changing. This yields we should use background-image instead and that background-color is used for the background of the selection.

Just setting the background-image to the color doesn't work, that gives a error because a image is expected. So now we have to figure out a way to make our color into something we can set as a background-image luckily the inspector shows us the way GTK does it internally namely by wrapping the color like this: linear-gradient(red). Doing so creates a uniform red image which can be used as the background.

Applying this knowledge to your code gives us:

if"red"in self.name_entry.get_text():
    self.gtk_provider.load_from_data('#name_entry { background-image: linear-gradient(red); }')
elif"green"in self.name_entry.get_text():
    self.gtk_provider.load_from_data('#name_entry { background-image: linear-gradient(green); }')

  1. I think there are better ways then the way I insert self.entry_default_background_color_str into the CSS text.

There is indeed a better way, namely don't do it. We can easily return to the default by just feeding the CssProvider an empty version of the css, this will overwrite the old one and thus remove any old style properties like for example the color.

Combining this with the previous section gives us:

if"red"in self.name_entry.get_text():
    self.gtk_provider.load_from_data('#name_entry { background-image: linear-gradient(red); }')
elif"green"in self.name_entry.get_text():
    self.gtk_provider.load_from_data('#name_entry { background-image: linear-gradient(green); }')
else:
    self.gtk_provider.load_from_data('#name_entry {}')

What is the best way to set background color for one entry and set it back to the default color?

Now that I addressed the issues with your code, now this all important question. The way your are doing it now is replacing the CSS file, which works fine but in the long run is really inefficient. Normally you would load the CSS and uses classes and ids to tell it which styling to apply.

Below I adapted your code to do it this way, check the comments for the explanation.

def__init__(self):

    screen = Gdk.Screen.get_default()
    gtk_provider = Gtk.CssProvider()
    gtk_context = Gtk.StyleContext()
    gtk_context.add_provider_for_screen(screen, gtk_provider, Gtk.STYLE_PROVIDER_PRIORITY_APPLICATION)

    # Create the window
    Gtk.Window.__init__(self, title="Check Input")
    self.set_size_request(300, 80)
    self.mainbox = Gtk.VBox()
    self.add(self.mainbox)

    # Load the CSS
    gtk_provider.load_from_data("""
    #name_entry.red { background-image: linear-gradient(red); }
    #name_entry.green { background-image: linear-gradient(green); }
    """)

    # Create the entry and give it a name which will be the ID
    name_entry = Gtk.Entry()
    name_entry.set_name("name_entry")
    self.mainbox.pack_start(name_entry, True, True, 0)

    # Add the listener
    name_entry.connect("changed", self.check_input)

    self.show_all()


defcheck_input(self, entry):
    # Get the style context for this widget
    entry_style_context = entry.get_style_context()

    # Check if our text contains redif"red"in entry.get_text():
        # Add the red class, so now the styling with .red is applied
        entry_style_context.add_class("red")

    # Check if our text contains greenelif"green"in entry.get_text():
        # Add the red class, so now the styling with .green is applied
        entry_style_context.add_class("green")
    else:
        # When the text doesn't contain it remove the color classes to show the default behaviour
        entry_style_context.remove_class("red")
        entry_style_context.remove_class("green")

Post a Comment for "Best Way To Set Entry Background Color In Python Gtk3 And Set Back To Default"