I want my ttk.treeview to have alternating colours

ghz 14hours ago ⋅ 13 views

I want my ttl.treeview table to have an alternating pattern of colours and I tried to add tags and make the background of each odd row distinct by using the tag_configure method, but I haven't been able.

Every row is a row taken from a db table that I want to show.

I also tried to do so in a little and separate program, but it hasn't been effective either.

def show(self, row, column, rowspan):
    self.row = row
    self.column = column
    self.rowspan = rowspan
    global FondoBase


    self.Tabla = ttk.Treeview(FondoBase, columns=self.Columnas[1:], height=40)

    self.Tabla.heading("#0", text=self.Columnas[0])
    for i in self.Columnas[1:]:
        self.Tabla.heading("{}".format(i), text="{}".format(i))

    self.Tabla.grid(row=row, column=column, rowspan=rowspan, sticky="e", pady=30)
    scrol = Scrollbar(FondoBase, command=self.Tabla.yview)

    self.Tabla.config(yscrollcommand=scrol.set)


    scrol.grid(row=row, column=column+1, sticky="wns", rowspan=rowspan, pady=30)



    Conexion = connect('{}'.format(Directorio))

    with Conexion:

        Seleccion = Conexion.cursor()

        Seleccion.execute("""SELECT * FROM {}""".format(self.nombre))

        resultado = Seleccion.fetchall()


    for i in range(len(resultado)):
        if i%2 == 0:
        self.Tabla.insert("", i, text="{}".format(resultado[i][0]), values=(resultado[i][1:]), tags=("par"))
            self.Tabla.tag_configure("par", background="#00ffff")

        else:
            self.Tabla.insert("", i, text="{}".format(resultado[i][0]), values=(resultado[i][1:]), tags=("impar"))

I don't really know what's going on.

Answer

The issue you're encountering is that you're using the tag_configure method inside the loop where you're inserting rows. As a result, you are defining the tag par and impar inside the loop, which means that tag_configure is getting called multiple times. This isn't necessary and could lead to unexpected behavior.

Here's a breakdown of what needs to be done:

  1. Define Tags Before Inserting Rows: Tags should be configured outside the loop. This way, you define the tag styles once, and then you can apply them to rows when inserting them.

  2. Correct Tagging: You need to ensure that the tags for alternating rows are applied correctly. Specifically, the "par" tag should be used for even rows, and the "impar" tag should be used for odd rows.

Here's the corrected code:

import tkinter as tk
from tkinter import ttk
from tkinter import Scrollbar
from sqlite3 import connect

class MyTreeviewApp:
    def __init__(self, master):
        self.master = master
        self.Tabla = None
        self.Columnas = ["ID", "Name", "Age"]  # Example columns, modify as needed
        self.nombre = "users"  # Example table name from your database
        
    def show(self, row, column, rowspan):
        global FondoBase
        
        # Define tags outside the loop
        self.Tabla = ttk.Treeview(FondoBase, columns=self.Columnas[1:], height=40)

        self.Tabla.heading("#0", text=self.Columnas[0])
        for i in self.Columnas[1:]:
            self.Tabla.heading("{}".format(i), text="{}".format(i))

        # Set up tags for alternating row colors
        self.Tabla.tag_configure("par", background="#00ffff")  # Even rows
        self.Tabla.tag_configure("impar", background="#ffcccb")  # Odd rows

        self.Tabla.grid(row=row, column=column, rowspan=rowspan, sticky="e", pady=30)
        scrol = Scrollbar(FondoBase, command=self.Tabla.yview)
        self.Tabla.config(yscrollcommand=scrol.set)
        scrol.grid(row=row, column=column+1, sticky="wns", rowspan=rowspan, pady=30)

        # Connect to database and fetch rows
        Conexion = connect('{}'.format(Directorio))
        with Conexion:
            Seleccion = Conexion.cursor()
            Seleccion.execute("""SELECT * FROM {}""".format(self.nombre))
            resultado = Seleccion.fetchall()

        # Insert rows into the table with alternating colors
        for i in range(len(resultado)):
            # Determine the tag based on whether the row is even or odd
            tag = "par" if i % 2 == 0 else "impar"
            
            # Insert the row into the table with the corresponding tag
            self.Tabla.insert("", i, text="{}".format(resultado[i][0]), values=(resultado[i][1:]), tags=(tag,))

# Assuming FondoBase is the parent frame where the treeview is placed
root = tk.Tk()
FondoBase = ttk.Frame(root)
FondoBase.grid(row=0, column=0)

app = MyTreeviewApp(root)
app.show(0, 0, 1)

root.mainloop()

Key Changes:

  1. Tag Configuration Outside the Loop: The tag_configure method is now called once before inserting rows, which ensures the tags are configured properly for row colors.

  2. Tag Assignment During Row Insertion: Inside the loop, based on whether the index i is even or odd, I assign the appropriate tag ("par" for even and "impar" for odd rows).

  3. Scrollbar: The scrollbar has been retained, but this is just a part of the layout where the treeview is placed, which is not changed.

Output:

Now, when you run the show function, your rows will have alternating background colors: one color for even rows ("par") and another for odd rows ("impar").

Notes:

  • Ensure that FondoBase and Directorio are properly defined in your code, as these are external variables that were not fully included in your original snippet.
  • Make sure your database query and results (resultado) are correctly retrieved. The column names (self.Columnas) should match the structure of the table you're querying.

This should give you the alternating color pattern you're aiming for in your ttk.Treeview.