如何在tkinter树形视图中更改选定单元格的前景或背景颜色?

2024-09-20 18:49:19 发布

您现在位置:Python中文网/ 问答频道 /正文

我想更改中选定单元格的前景或背景颜色tkinter.treeview公司. 我怎么能做到呢?在

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

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

我以前写过一篇test code。请使用此代码导出您的解决方案/建议。谢谢。在

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


Tags: 命令视图style颜色tkinterconfigurelink公司
2条回答
  1. @布莱诺克利说,人不能改变一个人的颜色 单元格输入ttk树景. 在
  2. 所以我试着用tk.帆布()和tk.Canvas.create_文本()至 创建一个在 ttk树景()小工具。我很幸运能来 j08lue/ttkcalendar.py有相同的目标和我 改编自它。在
  3. 我改编的剧本(和相关评论)如下所示。我 希望它能帮助其他人也这样想。在

需要改进:我还没有弄清楚为什么我的算法无法将画布文本框精确地覆盖在图标/树列和值列中选定的树视图单元格中的值上。为此,我求助于使用通过反复试验确定的值。然而,这并不理想。有人能分享一下我如何在不使用fudge值的情况下实现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()

如果您准备覆盖widget,您可能有非常定制的需求,或者可能有一个更适合您需要的widget。如果您不打算使用treeview,也许table小部件将提供您想要的东西。您可以控制单个单元格的内容,它允许用户编辑单元格(默认情况下),并且可以独立于其他单元格控制“活动”单元格属性。使用此代码将数据放入表中。在

import tkinter as tk
import tkinter.ttk as ttk
from tkinter.tktable import Table as ttkTable
from tkinter.tktable import ArrayVar

class App(tk.Frame):
    def __init__(self, parent, *args, **kwargs):
        ttk.Frame.__init__(self, parent, *args, **kwargs)
        self.grid_columnconfigure(0, weight=1)
        self.grid_rowconfigure(0, weight=1)
        parent.grid_columnconfigure(0, weight=1)
        parent.grid_rowconfigure(0, weight=1)
        self.content = ArrayVar(parent)
        self.table = ttkTable(rows=4,  cols=4,  titlerows=1,
            titlecols=0,    roworigin=0,    colorigin=0,   anchor='w', 
            selecttype='cell',   rowstretch='none',  colstretch='unset',
            flashmode='off', ellipsis='...', ipadx=2,    colwidth=12,
            multiline=False, resizeborders='col',   selectmode='browse',
            cursor='arrow', insertwidth=2, variable=self.content,
            insertbackground='white'
        )
        self.table.tag_configure('title', relief='raised', anchor='center', bg='blue',
            fg='white', state='disabled'
        )
        self.table.tag_configure('active', bg='gray30', fg='white')

        c_headers = ["Name", "Date", "Time", "Loc"]
        for col, word in enumerate(c_headers, start=0):
            index = '0,' + str(col)
            self.table.set('col', index, word)

        self.table.width((0,1,2,3), (30,30,30,40))

        self.table.set('row','1,0', "John","2017-02-05","11:30:23","Airport")
        self.table.set('row','2,0', "Betty","2014-06-25","18:00:00","Orchard Road")

        self.table.grid(sticky='news')

相关问题 更多 >

    热门问题