How to write a custom Gtk.CellRenderer which would show Gtk.ColorButton

1.4k views Asked by At

I am using Python 3 and Gtk+ 3. I have a list of colors stored in a Gtk.ListStore. I want to display these colors as Gtk.ColorButton with a Gtk.CellRenderer so that the users would be able to view the colors and also change the colors too. My problem is that I do not know how to render/draw these buttons with a custom Gtk.CellRenderer.

Here is my code:

class CellRendererColorButton(Gtk.CellRenderer):
    __gsignals__ = {
        'color-set': (GObject.SIGNAL_RUN_FIRST, None, (str,))
    }


    color = GObject.property(type=str, default='rgb(0,0,255)')

    def __init__(self):
        super().__init__()

    def do_set_property(self, pspec, value):
        setattr(self, pspec.name, value)

    def do_get_property(self, pspec):
        return getattr(self, pspec.name)

    # I have no idea about this
    # def do_get_size(self, widget, cell_area):
    #     pass

    def do_render(self, cr, widget, background_area, cell_area, flags):
        # selected = (flags & Gtk.CellRendererState.SELECTED) != 0
        # prelit = (flags & Gtk.CellRendererState.PRELIT) != 0
        color1 = Gdk.RGBA()
        succeed = color1.parse(self.color)
        if not succeed:
            color1.parse('rgb(0,0,255)')
        button = Gtk.ColorButton.new_with_rgba(color1)
        button.connect('color-set', self._on_color_set)
        # now how do you actually render this button???

    # now idea about this one too
    # def do_activate(self, event, widget, path, background_area, cell_area,
    #                 flags):
    #     pass

    def _on_color_set(self, button, data=None):
        self.emit("color-set", button.get_rgba().to_string())


class IcsListTreeView(Gtk.Box):
    """a Gtk.TreeView for displaying the ics event list"""
    def __init__(self, win):
        super().__init__(orientation=Gtk.Orientation.VERTICAL)
        self.win = win
        self.create_list_model()
        self.add_defaults_to_model()
        self.tree = Gtk.TreeView(self.store)
        self.add_model_to_tree()
        select = self.tree.get_selection()
        select.set_mode(Gtk.SelectionMode.BROWSE)
        # select.connect("changed", self.on_tree_selection_changed)
        self.sw = Gtk.ScrolledWindow()
        self.sw.set_policy(Gtk.PolicyType.AUTOMATIC, Gtk.PolicyType.AUTOMATIC)
        self.sw.add(self.tree)

        self.pack_start(self.sw, True, True, 0)
        self.show_all()

    def create_list_model(self):
        # enabled, editable, description, path, color
        self.store = Gtk.ListStore(bool, bool, str, str, str)

    def add_model_to_tree(self):
        renderer = Gtk.CellRendererToggle()
        renderer.connect('toggled', self._on_active_toggled)
        column = Gtk.TreeViewColumn("Enable", renderer, active=0)
        self.tree.append_column(column)

        renderer = Gtk.CellRendererText()
        renderer.connect('edited', self._on_description_edited)
        column = Gtk.TreeViewColumn("Description", renderer, text=2, editable=1)
        self.tree.append_column(column)

        renderer = CellRendererColorButton()
        renderer.connect('color-set', self._on_color_changed)
        column = Gtk.TreeViewColumn("Color", renderer, color=4)
        self.tree.append_column(column)

        renderer = Gtk.CellRendererText()
        renderer.connect('edited', self._on_url_edited)
        column = Gtk.TreeViewColumn("Path/Url", renderer, text=3, editable=1)
        self.tree.append_column(column)

    def add_defaults_to_model(self):
        self.store.append(
            [True, False, 'Holidays of Iran',
             'https://www.google.com/calendar/ical/en.ir%23holi' +
                'day%40group.v.calendar.google.com/public/basic.ics', 'blue'])
        self.store.append([False, True, '', '', ''])

    def _on_color_changed(self, cell, path, color, data=None):
        iter1 = self.store.get_iter(path)
        self.store[iter1][4] = color

I have found this question to be relevant but I cannot figure it out still. I also found this gem too but it is too complicated for me to understand :).

0

There are 0 answers