如何在tkinter treeview中更改所选单元格的前景色或背景色?

时间:2018-01-20 15:54:37

标签: python tkinter colors treeview

我想在tkinter.treeview中更改所选单元格的前景色或背景色。我怎么能这样做?

这个link显示了更改树视图中所有单元格颜色的命令,但我无法使其适用于单个单元格。

ttk.Style().configure("Treeview", background="#383838", 
 foreground="white", fieldbackground="red")

我之前写过test code。请使用此代码来获得您的解决方案/建议。谢谢。

这个link显示了如何使用标签来改变一行数据的颜色,即一个选定的项目,而不是一个单元格。

4 个答案:

答案 0 :(得分:1)

如果您准备叠加小部件,则可能有非常自定义的要求,或者可能有更适合您需求的小部件。如果您不习惯使用树视图,那么表格小部件可能会提供您想要的内容。您可以控制单个单元格内容,它允许用户编辑单元格(默认情况下),您可以与其他单元格分开控制“活动”单元格属性。您的数据使用此代码放在表格中。

2016, 68.41987090116676
2017, 88.9788618486191
2018, 90.94850458504749
2019, 113.20946182004333
2020, 115.71547492850719

答案 1 :(得分:1)

我相信您可以通过非常简单的方式获得所需的行为:

  1. 将标签分配给您的单元格

In this question you can see both how to insert tags and how to change them

  1. 为每个标签分配颜色

Like suggested in this question

  1. 请注意,Tkinter有点老而且被解散了……您可能会遇到一些困难,所以让我已经将其链接:

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()

结果:

After the first click

After the second click

答案 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)

  1. @BryanOkley分享了一个人无法改变个人的颜色 ttk.Treeview中的细胞。
  2. 所以我探索了使用tk.Canvas()和tk.Canvas.create_text()来     创造改变一个选定单元格颜色的错觉     ttk.Treeview()小部件。我很幸运能够过来     j08lue/ttkcalendar.py我有同样的目标     改编自它。
  3. 我的改编剧本(附有相关评论)如下所示。一世     希望它可以帮助其他人考虑做同样的事情。
  4. 需要改进:我还没弄清楚为什么我的算法无法准确地将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()