我想在tkinter.treeview中更改所选单元格的前景色或背景色。我怎么能这样做?
这个link显示了更改树视图中所有单元格颜色的命令,但我无法使其适用于单个单元格。
ttk.Style().configure("Treeview", background="#383838",
foreground="white", fieldbackground="red")
我之前写过test code。请使用此代码来获得您的解决方案/建议。谢谢。
这个link显示了如何使用标签来改变一行数据的颜色,即一个选定的项目,而不是一个单元格。
答案 0 :(得分:1)
如果您准备叠加小部件,则可能有非常自定义的要求,或者可能有更适合您需求的小部件。如果您不习惯使用树视图,那么表格小部件可能会提供您想要的内容。您可以控制单个单元格内容,它允许用户编辑单元格(默认情况下),您可以与其他单元格分开控制“活动”单元格属性。您的数据使用此代码放在表格中。
2016, 68.41987090116676
2017, 88.9788618486191
2018, 90.94850458504749
2019, 113.20946182004333
2020, 115.71547492850719
答案 1 :(得分:1)
我相信您可以通过非常简单的方式获得所需的行为:
In this question you can see both how to insert tags and how to change them
Like suggested in this question
Why my code below may not work properly
请注意,您询问的是“如何更改选定的单元格”,但是从您写的内容来看,我认为您正在尝试更改选定的行。我下面的代码更改了行。
import tkinter as tk
from tkinter import ttk
from random import choice
colors = ["red", "green", "black", "blue", "white", "yellow", "orange", "pink", "grey", "purple", "brown"]
def recolor():
for child in tree.get_children():
picked = choice(colors)
tree.item(child, tags=(picked), values=(picked))
for color in colors:
tree.tag_configure(color, background=color)
tree.tag_configure("red", background="red")
root = tk.Tk()
tree=ttk.Treeview(root)
tree["columns"]=("one","two","three")
tree.column("#0", width=60, minwidth=30, stretch=tk.NO)
tree.column("one", width=120, minwidth=30, stretch=tk.NO)
tree.heading("#0",text="0",anchor=tk.W)
tree.heading("one", text="1",anchor=tk.W)
for i in range(10):
tree.insert("", i, text="Elem"+str(i), values=("none"))
tree.pack(side=tk.TOP,fill=tk.X)
b = tk.Button(root, text="Change", command=recolor)
b.pack()
root.mainloop()
答案 2 :(得分:1)
如果有人在寻找答案以更改tkinter树视图的选定颜色,则可以检查以下代码。
style = ttk.Style()
# this is set background and foreground of the treeview
style.configure("Treeview",
background="#E1E1E1",
foreground="#000000",
rowheight=25,
fieldbackground="#E1E1E1")
# set backgound and foreground color when selected
style.map('Treeview', background=[('selected', '#BFBFBF'), foreground=[('selected', 'black')])
答案 3 :(得分:0)
需要改进:我还没弄清楚为什么我的算法无法准确地将Canvas文本框覆盖在图标/树列和值列中所选Treeview单元格中的值上。为此,我采用了通过试验和测试确定的软糖价值。错误。但是,这并不理想。 有人可以分享如何在不使用软糖值的情况下实现canvas_textbox叠加与Treeview单元格值的准确对齐吗?
import tkinter as tk
import tkinter.ttk as ttk
import tkinter.font as tkFont
class App(tk.Frame):
def __init__(self, parent, *args, **kwargs):
ttk.Frame.__init__(self, parent, *args, **kwargs)
#1. Create Treeview with binding
self.tree = ttk.Treeview(parent, columns=("size", "modified"))
self.tree["columns"] = ("date", "time", "loc")
self.tree.column("#0", width=100, anchor='center')
self.tree.column("date", width=100, anchor='center')
self.tree.column("time", width=100, anchor='center')
self.tree.column("loc", width=100, anchor='center')
self.tree.heading("#0", text="Name")
self.tree.heading("date", text="Date")
self.tree.heading("time", text="Time")
self.tree.heading("loc", text="Location")
self.tree.insert("","end", text = "Grace",
values = ("2010-09-23","03:44:53","Garden"))
self.tree.insert("","end", text = "John" ,
values = ("2017-02-05","11:30:23","Airport"))
self.tree.insert("","end", text = "Betty",
values = ("2014-06-25","18:00:00",""))
self.tree.grid()
self.tree.bind('<ButtonRelease-1>', self.selectItem)
#2. Create a Canvas Overlay to show selected Treeview cell
sel_bg = '#ecffc4'
sel_fg = '#05640e'
self.setup_selection(sel_bg, sel_fg)
def setup_selection(self, sel_bg, sel_fg):
self._font = tkFont.Font()
self._canvas = tk.Canvas(self.tree,
background=sel_bg,
borderwidth=0,
highlightthickness=0)
self._canvas.text = self._canvas.create_text(0, 0,
fill=sel_fg,
anchor='w')
def selectItem(self, event):
# Remove Canvas overlay from GUI
self._canvas.place_forget()
# Local Parameters
x, y, widget = event.x, event.y, event.widget
item = widget.item(widget.focus())
itemText = item['text']
itemValues = item['values']
iid = widget.identify_row(y)
column = event.widget.identify_column(x)
print ('\n&&&&&&&& def selectItem(self, event):')
print ('item = ', item)
print ('itemText = ', itemText)
print('itemValues = ',itemValues)
print ('iid = ', iid)
print ('column = ', column)
#Leave method if mouse pointer clicks on Treeview area without data
if not column or not iid:
return
#Leave method if selected item's value is empty
if not len(itemValues):
return
#Get value of selected Treeview cell
if column == '#0':
self.cell_value = itemText
else:
self.cell_value = itemValues[int(column[1]) - 1]
print('column[1] = ',column[1])
print('self.cell_value = ',self.cell_value)
#Leave method if selected Treeview cell is empty
if not self.cell_value: # date is empty
return
#Get the bounding box of selected cell, a tuple (x, y, w, h), where
# x, y are coordinates of the upper left corner of that cell relative
# to the widget, and
# w, h are width and height of the cell in pixels.
# If the item is not visible, the method returns an empty string.
bbox = widget.bbox(iid, column)
print('bbox = ', bbox)
if not bbox: # item is not visible
return
# Update and show selection in Canvas Overlay
self.show_selection(widget, bbox, column)
print('Selected Cell Value = ', self.cell_value)
def show_selection(self, parent, bbox, column):
"""Configure canvas and canvas-textbox for a new selection."""
print('@@@@ def show_selection(self, parent, bbox, column):')
x, y, width, height = bbox
fudgeTreeColumnx = 19 #Determined by trial & error
fudgeColumnx = 15 #Determined by trial & error
# Number of pixels of cell value in horizontal direction
textw = self._font.measure(self.cell_value)
print('textw = ',textw)
# Make Canvas size to fit selected cell
self._canvas.configure(width=width, height=height)
# Position canvas-textbox in Canvas
print('self._canvas.coords(self._canvas.text) = ',
self._canvas.coords(self._canvas.text))
if column == '#0':
self._canvas.coords(self._canvas.text,
fudgeTreeColumnx,
height/2)
else:
self._canvas.coords(self._canvas.text,
(width-(textw-fudgeColumnx))/2.0,
height/2)
# Update value of canvas-textbox with the value of the selected cell.
self._canvas.itemconfigure(self._canvas.text, text=self.cell_value)
# Overlay Canvas over Treeview cell
self._canvas.place(in_=parent, x=x, y=y)
if __name__ == "__main__":
window = tk.Tk()
app = App(window)
window.mainloop()