'tkinter Highlight a row of a label table
I am trying to highlight an entire row of a table created with buttons.
The code already highlights the button the mouse is over, but I need to highlight not only this button, but also the entire row to emulate a real table.
I know this is easier to do with a tree view, but for multiple reasons in my GUI, I am forced to use a button based table instead of a tree view.
from tkinter import *
root = Tk()
class HoverButton(Button):
def __init__(self, master, **kw):
Button.__init__(self,master=master,**kw)
self.defaultBackground = self["background"]
self.bind("<Enter>", self.on_enter)
self.bind("<Leave>", self.on_leave)
def on_enter(self, e):
self['background'] = self['activebackground']
def on_leave(self, e):
self['background'] = self.defaultBackground
columns = ("column 1","column 2","column 3", "column 4")
first_row = ("data 1", "data 2", "data 3", "data 4")
for columns_headings in range(len(columns)):
l = HoverButton(root, text=columns[columns_headings], relief=RIDGE, activebackground="yellow")
l.grid(row=0, column=columns_headings, sticky=NSEW)
for first_row_data in range(len(first_row)):
g = HoverButton(root, text=first_row[first_row_data], relief=RIDGE, activebackground="yellow")
g.grid(row=1, column=first_row_data, sticky=NSEW)
mainloop()
Solution 1:[1]
You can use .grid_info() to get the row of the hovered button and then update all the buttons in same row (get by .grid_slaves(row=...):
def on_enter(self, e):
row = self.grid_info()['row']
for w in self.master.grid_slaves(row=row):
if isinstance(w, HoverButton):
w['bg'] = w['activebackground']
def on_leave(self, e):
row = self.grid_info()['row']
for w in self.master.grid_slaves(row=row):
if isinstance(w, HoverButton):
w['bg'] = w.defaultBackground
Solution 2:[2]
If you will keep buttons on 2D list with rows and columns then you can simply access other buttons in the same row. Every button need also variable to keep its row number.
from tkinter import *
root = Tk()
class HoverButton(Button):
def __init__(self, master, **kw):
Button.__init__(self,master=master,**kw)
self.defaultBackground = self["background"]
self.bind("<Enter>", self.on_enter)
self.bind("<Leave>", self.on_leave)
def on_enter(self, e):
#self['background'] = self['activebackground']
for b in buttons[self.row_number]:
b['background'] = self['activebackground']
def on_leave(self, e):
#self['background'] = self.defaultBackground
for b in buttons[self.row_number]:
b['background'] = self.defaultBackground
columns = ("column 1","column 2","column 3", "column 4")
first_row = ("data 1", "data 2", "data 3", "data 4")
buttons = [] # list 2D for all buttons
row = []
for columns_headings in range(len(columns)):
l = HoverButton(root, text=columns[columns_headings], relief=RIDGE, activebackground="yellow")
l.row_number = 0
l.grid(row=0, column=columns_headings, sticky=NSEW)
row.append(l)
buttons.append(row)
row = []
for first_row_data in range(len(first_row)):
g = HoverButton(root, text=first_row[first_row_data], relief=RIDGE, activebackground="yellow")
g.row_number = 1
g.grid(row=1, column=first_row_data, sticky=NSEW)
row.append(g)
buttons.append(row)
mainloop()
EDIT:
Version with more rows - which need extra for-loop.
import tkinter as tk # PEP8: `import *` is not preferred
# --- classes --- # PEP8: all classes directly after imports
class HoverButton(tk.Button):
def __init__(self, master, **kw):
super().__init__(master=master, **kw)
self.defaultBackground = self["background"]
self.bind("<Enter>", self.on_enter)
self.bind("<Leave>", self.on_leave)
def on_enter(self, e):
#self['background'] = self['activebackground']
for b in buttons[self.row_number]:
b['background'] = self['activebackground']
def on_leave(self, e):
#self['background'] = self.defaultBackground
for b in buttons[self.row_number]:
b['background'] = self.defaultBackground
# --- main ---
root = tk.Tk()
columns = ("column 1","column 2","column 3", "column 4")
rows = [
("data A1", "data A2", "data A3", "data A4"),
("data B1", "data B2", "data B3", "data B4"),
("data C1", "data C2", "data C3", "data C4"),
]
buttons = []
row = []
for col_number, text in enumerate(columns):
l = HoverButton(root, text=text, relief='ridge', activebackground="yellow")
l.row_number = 0
#l.col_number = col_number
l.grid(row=0, column=col_number, sticky='nsew')
row.append(l)
buttons.append(row)
for row_number, row_data in enumerate(rows, 1):
row = []
for col_number, text in enumerate(row_data):
g = HoverButton(root, text=text, relief='ridge', activebackground="yellow")
g.row_number = row_number
#g.col_number = col_number
g.grid(row=row_number, column=col_number, sticky='nsew')
row.append(g)
buttons.append(row)
root.mainloop()
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | acw1668 |
| Solution 2 |

