tkinter 突出显示一行标签 table
tkinter Highlight a row of a label table
我正在尝试突出显示使用按钮创建的 table 的整行。
代码已经突出显示了鼠标悬停的按钮,但我不仅需要突出显示此按钮,还需要突出显示整行以模拟真实的 table。
我知道使用树视图更容易做到这一点,但出于多种原因,在我的 GUI 中,我不得不使用基于按钮 table 而不是树视图。
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()
如果您将按钮保留在带有行和列的二维列表中,那么您可以简单地访问同一行中的其他按钮。每个按钮还需要变量来保持其行号。
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()
编辑:
具有更多行的版本 - 需要额外的 for
-循环。
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()
您可以将所有 Label
设置在与鼠标悬停的行相同的行中。我添加了几行数据以使事情更清楚。
请注意 header 行正常突出显示。
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):
row = e.widget.grid_info()['row']
if not row: # Header row?
self['background'] = self['activebackground']
else:
for lbl in row_labels[row]:
lbl['background'] = lbl['activebackground']
def on_leave(self, e):
row = e.widget.grid_info()['row']
if not row: # Header row?
self['background'] = self.defaultBackground
else:
for lbl in row_labels[row]:
lbl['background'] = lbl.defaultBackground
columns = ("column 1","column 2","column 3", "column 4")
rows = [("data 1A", "data 2A", "data 3A", "data 4A"),
("data 1B", "data 2B", "data 3B", "data 4B"),
("data 1C", "data 2C", "data 3C", "data 4C")]
# Create table of Labels.
row_labels = [] # List of lists of Labels.
labels = []
for j, column_heading in enumerate(columns):
l = HoverButton(root, text=column_heading, relief=RIDGE, activebackground="yellow")
l.grid(row=0, column=j, sticky=NSEW)
labels.append(l)
row_labels.append(labels)
for i, row in enumerate(rows, start=1):
labels = []
for j, item in enumerate(row):
g = HoverButton(root, text=item, relief=RIDGE, activebackground="yellow")
g.grid(row=i, column=j, sticky=NSEW)
labels.append(g)
row_labels.append(labels)
root.mainloop()
截图如下:
您可以使用 .grid_info()
获取悬停按钮的行,然后更新同一行中的所有按钮(通过 .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
我正在尝试突出显示使用按钮创建的 table 的整行。
代码已经突出显示了鼠标悬停的按钮,但我不仅需要突出显示此按钮,还需要突出显示整行以模拟真实的 table。
我知道使用树视图更容易做到这一点,但出于多种原因,在我的 GUI 中,我不得不使用基于按钮 table 而不是树视图。
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()
如果您将按钮保留在带有行和列的二维列表中,那么您可以简单地访问同一行中的其他按钮。每个按钮还需要变量来保持其行号。
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()
编辑:
具有更多行的版本 - 需要额外的 for
-循环。
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()
您可以将所有 Label
设置在与鼠标悬停的行相同的行中。我添加了几行数据以使事情更清楚。
请注意 header 行正常突出显示。
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):
row = e.widget.grid_info()['row']
if not row: # Header row?
self['background'] = self['activebackground']
else:
for lbl in row_labels[row]:
lbl['background'] = lbl['activebackground']
def on_leave(self, e):
row = e.widget.grid_info()['row']
if not row: # Header row?
self['background'] = self.defaultBackground
else:
for lbl in row_labels[row]:
lbl['background'] = lbl.defaultBackground
columns = ("column 1","column 2","column 3", "column 4")
rows = [("data 1A", "data 2A", "data 3A", "data 4A"),
("data 1B", "data 2B", "data 3B", "data 4B"),
("data 1C", "data 2C", "data 3C", "data 4C")]
# Create table of Labels.
row_labels = [] # List of lists of Labels.
labels = []
for j, column_heading in enumerate(columns):
l = HoverButton(root, text=column_heading, relief=RIDGE, activebackground="yellow")
l.grid(row=0, column=j, sticky=NSEW)
labels.append(l)
row_labels.append(labels)
for i, row in enumerate(rows, start=1):
labels = []
for j, item in enumerate(row):
g = HoverButton(root, text=item, relief=RIDGE, activebackground="yellow")
g.grid(row=i, column=j, sticky=NSEW)
labels.append(g)
row_labels.append(labels)
root.mainloop()
截图如下:
您可以使用 .grid_info()
获取悬停按钮的行,然后更新同一行中的所有按钮(通过 .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