Best way to set Entry Background Color in Python GTK3 and set back to default
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.
- 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); }')
- 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()
def check_input(self, entry):
# Get the style context for this widget
entry_style_context = entry.get_style_context()
# Check if our text contains red
if "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 green
elif "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")
Change Background color of Gtk.Entry in Gtk3
You can use entry.override_background_color(Gtk.StateFlags.NORMAL, ...)
(not override_bg()
) or you can create some CSS:
provider = Gtk.CssProvider()
provider.load_from_data('.entry { background: red; }')
Gtk.StyleContext.add_provider_for_screen(Gdk.Screen.get_default(), provider,
Gtk.STYLE_PROVIDER_PRIORITY_APPLICATION)
GTK3 reuse CSS state background colors
The color you're looking for is probably @base_color
, for historical reasons. GTK has always had a distinction between "base" colors (for text entry widgets) and "background" colors (for everything else.)
It's not quite documentation, but examples are available on this page.
Python: Changing the select colour in a GtkTreeview
gtk_widget_modify_base
has been deprecated since 3.0. You could have used gtk_widget_override_background_color
, if it wasn't deprecated since 3.16. It's documentation states that:
If you wish to change the way a widget renders its background you should use a custom CSS style
However, if you want to disable selection color, the simpliest way is to unselect.
Your "changed"
signal callback might look something like this:
def changed_cb(selection):
model, iter = get_selected (selection)
# if there is no selection, iter is None
if iter is None:
return
# do something useful
# now unselect
path = model.get_path(iter)
selection.unselect_path(path)
path.free() # not sure if python frees it automatically
Gtk3+ How to change Gtk.Entry border to a color?
Gtk+ 3.x uses CSS to style and theme the widgets. The CSS structure, style classes, did change from 3.0 up to 3.26. This means that it's important to know the version you are using.
With Gtk+ 3.22 you can use the css:
entry {
border-color: Red;
}
With Gtk+ 3.18 use:
.entry {
border-color: Red;
}
Copy this css code to a file called test.css, then use this adapted example from the python gt3 tutorial:
import gi
gi.require_version('Gtk', '3.0')
from gi.repository import Gtk, Gdk, GObject
class EntryWindow(Gtk.Window):
def __init__(self):
Gtk.Window.__init__(self, title="Entry Demo")
self.set_size_request(200, 100)
self.timeout_id = None
vbox = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, spacing=6)
self.add(vbox)
self.entry = Gtk.Entry()
self.entry.set_text("Hello World")
vbox.pack_start(self.entry, True, True, 0)
hbox = Gtk.Box(spacing=6)
vbox.pack_start(hbox, True, True, 0)
self.check_editable = Gtk.CheckButton("Editable")
self.check_editable.connect("toggled", self.on_editable_toggled)
self.check_editable.set_active(True)
hbox.pack_start(self.check_editable, True, True, 0)
self.check_visible = Gtk.CheckButton("Visible")
self.check_visible.connect("toggled", self.on_visible_toggled)
self.check_visible.set_active(True)
hbox.pack_start(self.check_visible, True, True, 0)
self.pulse = Gtk.CheckButton("Pulse")
self.pulse.connect("toggled", self.on_pulse_toggled)
self.pulse.set_active(False)
hbox.pack_start(self.pulse, True, True, 0)
self.icon = Gtk.CheckButton("Icon")
self.icon.connect("toggled", self.on_icon_toggled)
self.icon.set_active(False)
hbox.pack_start(self.icon, True, True, 0)
def on_editable_toggled(self, button):
value = button.get_active()
self.entry.set_editable(value)
def on_visible_toggled(self, button):
value = button.get_active()
self.entry.set_visibility(value)
def on_pulse_toggled(self, button):
if button.get_active():
self.entry.set_progress_pulse_step(0.2)
# Call self.do_pulse every 100 ms
self.timeout_id = GObject.timeout_add(100, self.do_pulse, None)
else:
# Don't call self.do_pulse anymore
GObject.source_remove(self.timeout_id)
self.timeout_id = None
self.entry.set_progress_pulse_step(0)
def do_pulse(self, user_data):
self.entry.progress_pulse()
return True
def on_icon_toggled(self, button):
if button.get_active():
icon_name = "system-search-symbolic"
else:
icon_name = None
self.entry.set_icon_from_icon_name(Gtk.EntryIconPosition.PRIMARY,
icon_name)
win = EntryWindow()
style_provider = Gtk.CssProvider()
style_provider.load_from_path("test.css")
Gtk.StyleContext.add_provider_for_screen(
Gdk.Screen.get_default(),
style_provider,
Gtk.STYLE_PROVIDER_PRIORITY_APPLICATION
)
win.connect("delete-event", Gtk.main_quit)
win.show_all()
Gtk.main()
The result should be similar to this:
EDIT:
Result on Fedora 23 (Gtk+ 3.18.9):
How to set the background color in a Gtk3::TreeViewColumn?
The problem is this line:
my $column = Gtk3::TreeViewColumn->new_with_attributes
($c, $renderer, text => $n, background => $red);
Here, the background
attribute expects a Gtk3::ListStore
index, but you are not giving an integer index, rather you are supplying the RGBA object $red
.
Here is an example of how you can do it by adding a dummy column to the Gtk::ListStore
containing the color as a RGB string:
use feature qw(say);
use strict;
use warnings;
use Gtk3 -init;
use Glib 'TRUE', 'FALSE';
my @COLUMNS = qw( a b c );
my $ncols = scalar @COLUMNS;
my $red = "#f00";
my $window = Gtk3::Window->new ('toplevel');
my $notebook = Gtk3::Notebook->new;
$window->add($notebook);
my $sw = Gtk3::ScrolledWindow->new (undef, undef);
$notebook->append_page ($sw, Gtk3::Label->new ("tab"));
my $model = Gtk3::ListStore->new ((('Glib::String') x $ncols), 'Glib::String');
my $row = $model->append ();
$model->set ($row, (map {($_, $COLUMNS[$_])} 0..$#COLUMNS), $ncols, $red);
my $treeview = Gtk3::TreeView->new($model);
$sw->add($treeview);
while (my ($n, $c) = each @COLUMNS) {
my $renderer = Gtk3::CellRendererText->new;
my $column = Gtk3::TreeViewColumn->new_with_attributes
($c, $renderer, text => $n, background => $ncols);
$treeview->append_column($column);
}
$window->signal_connect( destroy => sub { Gtk3->main_quit() } );
$window->show_all;
Gtk3->main();
See also Python 3 and Gtk+3 - issue with TreeView and alternate colors of rows
How do I change a Gtk3 Entry text color in Python3?
Set the alpha channel to 1.0:
self.myOkEntry.override_color(Gtk.StateFlags.NORMAL, Gdk.RGBA(0.0, 1.0, 0.0, 1.0))
How to make buttons different colours in Python GTK3 (using gi)?
The preferred way in GTK3 is to use CSS for styling. Under Ubuntu 12.04 you may need to use background instead of background-color. But I don't know Python so I'll just give a link.
https://thegnomejournal.wordpress.com/2011/03/15/styling-gtk-with-css/
Related Topics
Passing a Matplotlib Figure to HTML (Flask)
Calling R Script from Python Using Rpy2
Optimizing for Accuracy Instead of Loss in Keras Model
Does Ruby Support Conditional Regular Expressions
Call a Function with Argument List in Python
Possible to Share In-Memory Data Between 2 Separate Processes
How to Build a Recursive Function in Python
Fastapi Runs API-Calls in Serial Instead of Parallel Fashion
Renaming a Virtualenv Folder Without Breaking It
Putting an If-Elif-Else Statement on One Line
Pandas Read_HTML Valueerror: No Tables Found
Generate Correlated Data in Python (3.3)
How to Use Rpy2 to Save a Pandas Dataframe to an .Rdata File
How to Import a JSON from a File on Cloud Storage to Bigquery
How to Import CSV Data into Django Models