Search code examples
pythoncolorsgtk3pygobject

Python GTK Color Chooser Widget - Set Color


I am writing a program using Python3 and GTK3 (via gi.repository). I want the color chooser to change its selected color when a RGB value is typed in the entry box and "Convert" is clicked. The "set_rgba()" command (found at http://learngtk.org/tutorials/python_gtk3_tutorial/html/colorchooser.html) is not changing the selected color. No error messages are generated (I executed the Python script from a terminal).

My program

The file contains functions for each button, so I will include the relevant snippets of code.

class ColorWin():
    """Color Dialog"""
    def __init__(self):
        self.ui = Gtk.Builder()
        self.ui.add_from_string(buffer=_GCOLOR)
        global _cc
        global _entry_rgb, _entry_hsi, _entry_hsl
        global _entry_hsv, _entry_cmyk, _entry_yiq
        _cc = self.ui.get_object('cc')
        _entry_rgb = self.ui.get_object('entry_rgb')
        _entry_hsi = self.ui.get_object('entry_hsi')
        _entry_hsl = self.ui.get_object('entry_hsl')
        _entry_hsv = self.ui.get_object('entry_hsv')
        _entry_cmyk = self.ui.get_object('entry_cmyk')
        _entry_yiq = self.ui.get_object('entry_yiq')
        # Match signal to function (handler)
        dic = {
            '_winexit' : Gtk.main_quit,
            '_submit_color': self._submit_color,
            'conv_color': self.conv_color,
            'conv_rgb': self.conv_rgb,
            'conv_hsi': self.conv_hsi,
            'conv_hsl': self.conv_hsl,
            'conv_hsv': self.conv_hsv,
            'conv_cmyk': self.conv_cmyk,
            'conv_yiq': self.conv_yiq,
        }
        self.ui.connect_signals(dic)

The function for the convert button

def conv_rgb(self, _entry_rgb):
    """Convert RGB to *"""
    _rgb = _entry_rgb.get_text()
    _round = 6
    _red = re.sub('\(([0-9.]+), ([0-9.]+), ([0-9.]+)\)', r'\1', _rgb)
    _green = re.sub('\(([0-9.]+), ([0-9.]+), ([0-9.]+)\)', r'\2', _rgb)
    _blue = re.sub('\(([0-9.]+), ([0-9.]+), ([0-9.]+)\)', r'\3', _rgb)
    _red = round(float(_red), _round)
    _green = round(float(_green), _round)
    _blue = round(float(_blue), _round)
    _rgba_gdk = Gdk.RGBA(_red, _green, _blue, 1.000)
    _cc.set_rgba(_rgba_gdk)

I have used print functions to print the value of each variable to the terminal. I have verified that the values and datatypes are correct. The "_rgba_gdk" is an Gdk.RGBA object (as it should be). "_cc" is the color chooser. I can use _cc.get_rgba() to get the currently selected value. However, I want to change it (via _cc.set_rgba(_rgba_gdk)) to the value in the RGB entry box (gotten from _entry_rgb.get_text()). This will allow users to see the color associated with the typed RGB value (the alpha is assumed to be 1 if no alpha is specified).


Solution

  • The problem seems to be get/set_rgba() is working with the currently selected color in the widgets "swatch" mode but not the editor mode (show-editor=True). When in editor mode, changing the editor updates the current color as well, but the data binding is not bi-directional. All I can offer is a hack which forces the editor to update after a new color is set:

    from gi.repository import Gtk
    from gi.repository import Gdk
    
    window = Gtk.Window()
    window.connect("destroy", Gtk.main_quit)
    
    box = Gtk.Box(orientation=Gtk.Orientation.VERTICAL)
    window.add(box)
    
    colorchooser = Gtk.ColorChooserWidget(show_editor=True)
    box.add(colorchooser)
    
    entry = Gtk.Entry(text='0.5, 0.5, 0.5, 1.0')
    box.add(entry)
    
    def on_button_clicked(button):
        values = [float(v) for v in entry.get_text().split(',')]
        colorchooser.set_rgba(Gdk.RGBA(*values))
        colorchooser.set_property("show-editor", True)
    
    button = Gtk.Button(label="Parse RGBA")
    button.connect("clicked", on_button_clicked)
    box.add(button)
    
    window.show_all()
    Gtk.main()
    

    Note colorchooser.set_property("show-editor", True) in the button clicked callback. This may or may not work in all versions of GTK+. I would log this as a bug requesting the color editor mode be updated if set_rgba() is called: https://bugzilla.gnome.org/enter_bug.cgi?product=gtk%2B