Python Tkinter, change specific row background colour?

Question:

I’ve been able to change the background colour of the entire window and of specific labels through this,

master.configure(background = 'SteelBlue1')
titlelabel = Tkinter.Label(master, text="my Title", fg = "blue4", bg = "gray80").grid(row=0, column = 1)

Is there a simple way to make row 0 gray instead of just the area around the label? Thanks

Asked By: darrenvba

||

Answers:

If there is only the title on this row, you can use columspan so that the title span over all columns and expand the label horizontally:

import Tkinter

master = Tkinter.Tk()

master.configure(background='SteelBlue1')
master.columnconfigure(0, weight=1) # make the column 1 expand when the window is resized
nb_of_columns = 2 # to be replaced by the relevant number
titlelabel = Tkinter.Label(master, text="my Title", fg="blue4", bg ="gray80")
titlelabel.grid(row=0, column=0, sticky='ew', columnspan=nb_of_columns) # sticky='ew' expands the label horizontally

master.geometry('200x200')
master.mainloop()

Otherwise, the solution is to follow scotty3785 advice and use a frame:

import Tkinter

master = Tkinter.Tk()

master.configure(background='SteelBlue1')
master.columnconfigure(1, weight=1)

nb_of_columns = 2 # to be replaced by the relevant number
titleframe = Tkinter.Frame(master, bg ="gray80")
titleframe.grid(row=0, column=0, columnspan=nb_of_columns, sticky='ew')
titlelabel = Tkinter.Label(titleframe, text="my Title", fg="blue4", bg ="gray80")
titlelabel.grid(row=0, column=1)
# other widgets on the same row:
Tkinter.Button(titleframe, text='Ok').grid(row=0, column=2)

master.geometry('200x200')
master.mainloop()
Answered By: j_4321

I figured out a way to do this without using a Frame which wasn’t feasible in my implementation. You have to use a combination of sticky=tk.EW on the grid and justify/anchor on the label.

Here is a piece of my code that lists account names, balances, and account type in a grid. When you hover over one of the rows, the entire row will highlight without any gaps. The only frame being used is to hold all of the contents (which I needed to keep the columns neat and organized) — it doesn’t use a frame for each row.

import tkinter as tk
from tkinter import ttk

def show_accounts(self) -> None:
    account_frame = ttk.Frame(self.content_frame)
    account_frame.grid(column=0, row=0)

    ttk.Label(account_frame, text="Account").grid(column=0, row=0, sticky=tk.W, padx=(0,20))
    ttk.Label(account_frame, text="Balance").grid(column=1, row=0, sticky=tk.W, padx=(0,20))
    ttk.Label(account_frame, text="Type").grid(column=2, row=0, sticky=tk.W)
    ttk.Separator(account_frame).grid(column=0, row=1, sticky=tk.EW, columnspan=3)

    accounts = self.controller.get_accounts()
    
    for i, account in enumerate(accounts):
        account_name = ttk.Label(account_frame, text=str(account.name), justify=tk.LEFT, anchor=tk.W)
        account_name.grid(column=0, row=i+2, sticky=tk.EW, ipadx=20)

        account_balance = ttk.Label(account_frame, text=f"{account.balance:,.2f}", justify=tk.LEFT, anchor=tk.W)
        account_balance.grid(column=1, row=i+2, sticky=tk.EW, ipadx=20)
        
        account_type = ttk.Label(account_frame, text=AccountType(account.type).name.title(), justify=tk.LEFT, anchor=tk.W)
        account_type.grid(column=2, row=i+2, sticky=tk.EW)

        # Bindings
        account_name.bind("<Enter>", lambda e, account=account: self.highlight_account_row(e, account))
        account_name.bind("<Leave>", lambda e, account=account: self.unhighlight_account_row(e, account))

        # Save to dictionary
        self.widgets[f"{account.name}_name"] = account_name
        self.widgets[f"{account.name}_balance"] = account_balance
        self.widgets[f"{account.name}_type"] = account_type

def highlight_account_row(self, event, account):
    self.widgets[f"{account.name}_name"].configure(background="grey")
    self.widgets[f"{account.name}_balance"].configure(background="grey")
    self.widgets[f"{account.name}_type"].configure(background="grey")

def unhighlight_account_row(self, event, account):
    self.widgets[f"{account.name}_name"].configure(background="white")
    self.widgets[f"{account.name}_balance"].configure(background="white")
    self.widgets[f"{account.name}_type"].configure(background="white")
Answered By: brianj
Categories: questions Tags: , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.