Search code examples
pythonpython-3.xtreeviewgtk3

Python 3 and Gtk+3 - issue with TreeView and alternate colors of rows


I'm new in python and Gtk+3 development. I'm trying to create a Gui with Gtk+3 which contains a Gtk.TreeView. I'm trying to show the odd records of the TreeView in different color but i always fail. I searched all over the internet and StackOverFlow but i didn't find something helpful. I'm using Python 3.4.3. Can someone help?

#!/usr/bin/env python3
# -*- coding: ISO-8859-1 -*-
import gi
gi.require_version('Gtk', '3.0')
from gi.repository import Gtk, Gdk


xim = [("Oranges", 5), ("Apples", 3), ("Bananas", 1), ("Tomatoes", 4), ("Cucumber", 1), ("potatoes", 10),
       ("apricot", 100)]


window = Gtk.Window()
window.connect("destroy", lambda q: Gtk.main_quit())
liststore = Gtk.ListStore(str, int)
for i in range(len(xim)):
    liststore.append(xim[i])
treeview = Gtk.TreeView(model=liststore)
window.add(treeview)
treeviewcolumn = Gtk.TreeViewColumn("Item")
treeview.append_column(treeviewcolumn)
cellrenderertext = Gtk.CellRendererText()
treeviewcolumn.pack_start(cellrenderertext, True)
treeviewcolumn.add_attribute(cellrenderertext, "text", 0)
treeviewcolumn = Gtk.TreeViewColumn("Quantity")
treeview.append_column(treeviewcolumn)
cellrenderertext = Gtk.CellRendererText()
treeviewcolumn.pack_start(cellrenderertext, True)
treeviewcolumn.add_attribute(cellrenderertext, "text", 1)
css_provider = Gtk.CssProvider()
css = """
GtkTreeView row:nth-child(odd){background-color: #ccc}
            """
css_provider.load_from_data(css.encode())
Gtk.StyleContext.add_provider_for_screen(Gdk.Screen.get_default(),
                                         css_provider,
                                         Gtk.STYLE_PROVIDER_PRIORITY_APPLICATION)
window.show_all()
Gtk.main()

Solution

  • I know it should be better to use CSS to change the style of widgets, but there's another solution that works.

    Add another column in the ListStore with the background color value and add the attribute "background" to both CellRendererText. In this way, every row will recover the background property from the ListStore. You should use a different color for each row.

    This is your code modified with my technique:

    import gi
    gi.require_version('Gtk', '3.0')
    from gi.repository import Gtk, Gdk
    
    
    xim = [("Oranges", 5), ("Apples", 3), ("Bananas", 1), ("Tomatoes", 4), ("Cucumber", 1), ("potatoes", 10),
           ("apricot", 100)]
    
    window = Gtk.Window()
    window.connect("destroy", lambda q: Gtk.main_quit())
    liststore = Gtk.ListStore(str, int, str)
    for i in range(len(xim)):
        if i % 2 == 0:
            background_color = "#fff"
        else:
            background_color = "#bbb"
        liststore.append(xim[i] + (background_color,))
    
    treeview = Gtk.TreeView(model=liststore)
    window.add(treeview)
    treeviewcolumn = Gtk.TreeViewColumn("Item")
    treeview.append_column(treeviewcolumn)
    cellrenderertext = Gtk.CellRendererText()
    treeviewcolumn.pack_start(cellrenderertext, True)
    treeviewcolumn.add_attribute(cellrenderertext, "text", 0)
    treeviewcolumn.add_attribute(cellrenderertext, "background", 2)
    
    treeviewcolumn = Gtk.TreeViewColumn("Quantity")
    treeview.append_column(treeviewcolumn)
    cellrenderertext = Gtk.CellRendererText()
    treeviewcolumn.pack_start(cellrenderertext, True)
    treeviewcolumn.add_attribute(cellrenderertext, "text", 1)
    treeviewcolumn.add_attribute(cellrenderertext, "background", 2)
    
    window.show_all()
    Gtk.main()