1

I have a Gtk.Entry and would like to change his border to red whenever the user enter an invalid value. I am using Gtk+3 and Python3. Any inputs on this? I've seen "Gtk.Entry.set_inner_border()" is deprecated for gtk+ > 3.4.

EDIT1:

enter image description here

It seems that either my Gtk version or my OS don't like colors at all! I also have these 2 lines of code and my buttons don't have any color:

    button1.get_style_context().add_class('suggested-action')
    button2.get_style_context().add_class(Gtk.STYLE_CLASS_DESTRUCTIVE_ACTION)

My Gtk+3 version is 3.18. I guess this is the reason? Would you suggest me to upgrade or use the widget set_color functions?

I'm gonna investigate and in the worst of cases I might use Gtk.Widget.set_background_color which I tested and works fine, even if it does not affect the color of the border but the background of the text. Now I should figure out how to automatically select the text hehe.

Thank you so much anyways José

EDIT2:

No color is displayed with the following lines:

    b_add.get_style_context().add_class('suggested-action')
    b_remove.get_style_context().add_class(Gtk.STYLE_CLASS_DESTRUCTIVE_ACTION)

enter image description here

deko
  • 463
  • 1
  • 6
  • 17
  • 1
    I don't have a machine running Gtk+ 3.18 but monday i'll have and can check it. Another option is to run [GTK Inspector](https://wiki.gnome.org/Projects/GTK+/Inspector) and check which css style classes are being used. Give it a try. – José Fonte Oct 14 '17 at 14:55
  • I didn't know about this debugger. Looks cool. It says the class of those 2 buttons is the one I specified. I would love to see the colors, I want to upgrade hehe – deko Oct 15 '17 at 00:28
  • Hi check my edit. With Gtk+ 3.18 just add a dot before entry: `.entry` – José Fonte Oct 16 '17 at 11:19

1 Answers1

1

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:

enter image description here

EDIT:

Result on Fedora 23 (Gtk+ 3.18.9):

enter image description here

José Fonte
  • 4,016
  • 2
  • 16
  • 28
  • Hi José, first thank you for remember. I added the dot yet it isn't working yet. Are you sure your version is the 3.18? Maybe I am cheking mine wrong? I believe mine is 3.18.9. I am running the command "dpkg -l libgtk2.0-0 libgtk-3-0" – deko Oct 16 '17 at 11:51
  • 1
    @deko Yes. I'm using Fedora 23 with Gtk+ 3.18.9. I've added a screenshot from it using Gtk Inspector. I've also edited the css file to test it (test.css) and it works. – José Fonte Oct 16 '17 at 12:22
  • Interesting. I dont know, all I can think about is my ubuntu. I have exactly what you have. button1.get_style_context().add_class('suggested-action') button2.get_style_context().add_class(Gtk.STYLE_CLASS_DESTRUCTIVE_ACTION) Probably these lines work aswell on your machine. Thank you so much for your time, hopefully some people find answer here aswell. – deko Oct 16 '17 at 16:36
  • @deko don't use the classes `suggested-action` and/or `destructive-action` on checkbuttons. Use it on a normal button and you will see it change to blue/red color respectively. – José Fonte Oct 16 '17 at 18:40
  • I am using them on regular buttons and no color is displayed. Please check again the original post so you can see the new picture debugging the buttons. – deko Oct 17 '17 at 00:35
  • @deko not sure if this is a ubuntu thing... Don't have any ubuntu machine to test but should not be the reason. Can't help you on that. – José Fonte Oct 17 '17 at 10:43