6

The color can be set on creation:

cell.set_property("background", "orange")

But how can I access the cell widgets later?

What I try to do: Check if a value is valid and then color the cell green, else red.

I found no way to change the style with CssProvider.

#!/usr/bin/env python3
# -*- coding: utf-8 -*-


import gi
gi.require_version('Gtk', '3.0')
from gi.repository import Gtk
from gi.repository import Gdk

import os
from pprint import pprint


class MyTreeviewWindow(Gtk.Window):
    def __init__(self):

        # css provider
        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)
        self.css = """
                GtkButton.green{background: green;}
                GtkButton.white{background: white;}
                GtkCellRenderer{background: blue;}
                """
        gtk_provider.load_from_data(bytes(self.css.encode()))
        

        Gtk.Window.__init__(self, title="Overview")
        self.set_size_request(600, 400)
        self.mainbox = Gtk.VBox()
        self.add(self.mainbox)
        self.main_sw = Gtk.ScrolledWindow()
        self.mainbox.pack_start(self.main_sw, True, True, 0)
        button = Gtk.Button("Change Row Colors")
        button.connect("clicked", self.on_change_color_button_clicked)
        self.mainbox.pack_start(button, True, True, 0)
        self.create_treeview()
        self.show_all()  
    

    def on_change_color_button_clicked(self, widget):
        # color button widget
        entry_style_context = widget.get_style_context()
        if not entry_style_context.has_class("green"):
            entry_style_context.remove_class("white")
            entry_style_context.add_class("green")
        else:
            entry_style_context.remove_class("green")
            entry_style_context.add_class("white")
        # color liststore
        for row in self.liststore:                
            pass
            # ???
            # change row colors


    def create_treeview(self):        
        self.column_names = ["name", "city", "country"]
        self.liststore = Gtk.ListStore(str, str, str)
        self.liststore.append(["Max", "Berlin", "Germany"])
        self.liststore.append(["John", "London", "England"])
        self.liststore.append(["Juan", "Madrid", "Spain"])
        self.treeview = Gtk.TreeView(self.liststore)
        for column_number, column_name in enumerate(self.column_names):
            if column_number == 1:
                cell = Gtk.CellRendererCombo()
                store = Gtk.ListStore(str)
                cell.set_property("model", store)
                cell.set_property("text-column", 0)
                cell.set_property("has-entry", True)
                store.append(["Berlin"])
                store.append(["London"])
                store.append(["Madrid"])
            else:
                cell = Gtk.CellRendererText()
            # set all row colores to orange
            cell.set_property("background", "orange")
            cell.set_property("font", "Sans Bold 12")
            column = Gtk.TreeViewColumn(column_name, cell, text=column_number)
            self.treeview.append_column(column)
        self.main_sw.add(self.treeview)
    

    def main(self):
        Gtk.main()

if __name__ == "__main__":
    base = MyTreeviewWindow()
    base.main()
    

enter image description here

edit:

I searched a way to change the color without changing the Liststore, because with that I have to create another liststore column for every cell. But I found no way to do without. So I change it now with:

def on_change_color_button_clicked(self, widget):
    ...
    for row in self.liststore:    
        if row[0] == "Max":
             self.liststore[row.iter][3]= "purple"          
        if row[1] == "London":
             self.liststore[row.iter][4]= "blue"          
        if row[2] == "Spain":
             self.liststore[row.iter][5]= "red"          
...

def create_treeview(self):        
       self.column_names = ["name", "city", "country", "color01", "color02", "color03"]
        self.liststore = Gtk.ListStore(str, str, str, str, str, str)
        self.liststore.append(["Max", "Berlin", "Germany", "white", "white", "white"])
        self.liststore.append(["John", "London", "England", "white", "white", "white"])
        self.liststore.append(["Juan", "Madrid", "Spain", "white", "white", "white"])
    ...
    ...
    column = Gtk.TreeViewColumn(column_name, cell, text=column_number, background=column_number+3)
Community
  • 1
  • 1
oxidworks
  • 1,563
  • 1
  • 14
  • 37
  • 2
    With GtkTreeView, the rows and their content aren't widgets (that's why there's this cell-renderer paradigm, and it's a pretty bad design, actually). So there's no way to select the cells as widgets... the solution you have in your edit is after all not that bad. – gniourf_gniourf Feb 18 '18 at 16:56
  • Did you try to use only 1 extra column for all cells? Instead of `background=column_number+3` this should do the trick: `background=3`. – Gerhardh Mar 22 '18 at 10:28

0 Answers0