简体   繁体   English

ttk treeview:备用行 colors

[英]ttk treeview: alternate row colors

How can I set a style for treeview widgets so that alternate rows have different background colors, for example, rows 1,3,5 have white backgrounds and rows 2,4,6 have light blue-grey backgrounds?如何为treeview小部件设置样式,以便交替行具有不同的背景 colors,例如,第 1、3、5 行具有白色背景,第 2、4、6 行具有浅蓝灰色背景?

I'd also like to set gridlines .我还想设置gridlines

I had this same issue a few months ago.几个月前我遇到了同样的问题。

From the tk docs :tk 文档

You can assign a list of tags to each item using the "tags" 
item configuration option (again, when creating the item or later on).

Tag configuration options can then be specified, which will then 
apply to all items having that tag.

Basically, you apply one tag to all of the odd-numbered rows, a different tag to each of the even-numbered rows, and then configure the tags.基本上,您将一个标签应用于所有奇数行,将不同的标签应用于每个偶数行,然后配置标签。


When you create the items inside the treeview, add tags to them:在树视图中创建项目时,向它们添加标签:

tree.insert('', 'end', text = 'your text', tags = ('oddrow',))

This code creates an element in tree , and the tags argument assigns the tag 'oddrow' to the element.此代码在tree创建一个元素,并且tags参数将标签“oddrow”分配给该元素。

Once you've created all your elements with 'oddrow' and 'evenrow' tags, you can color the tags:使用“oddrow”和“evenrow”标签创建所有元素后,您可以为标签着色:

tree.tag_configure('oddrow', background='orange')
tree.tag_configure('evenrow', background='purple')

I realise this is an old question but just for the record configuring the tags just after creating the tree (ie when no items have yet been added to it) also works.我意识到这是一个老问题,但仅用于在创建树后(即尚未添加任何项目时)配置标签的记录也有效。 As items get inserted later on they will be given the background colour appropriate to their 'oddrow' or 'evenrow' tag.随着项目稍后插入,它们将被赋予适合其“oddrow”或“evenrow”标签的背景颜色。

this is runnable without any extra modules... could mess with the code to make it work with your own.这是无需任何额外模块即可运行的......可能会弄乱代码以使其与您自己的代码一起使用。

from Tkinter import *
import ttk

class Test(Frame):

    def __init__(self):
        Frame.__init__(self)
        self.pack()
        self.listbox()
        self.buttons()

    def listbox(self):
        global new_customer_lb

        scrollbar = Scrollbar(self, orient="vertical")
        new_customer_lb = ttk.Treeview(self, columns=('ID','First Name','Last Name'))
        new_customer_lb['show']='headings'
        new_customer_lb.heading('#1', text= 'ID')
        new_customer_lb.column('#1', width=50, stretch=NO)
        new_customer_lb.heading('#2', text= 'First Name')
        new_customer_lb.column('#2', width=100, stretch=NO)
        new_customer_lb.heading('#3', text= 'Last Name')
        new_customer_lb.column('#3', width=100, stretch=NO)
        new_customer_lb.configure(yscroll = scrollbar.set, selectmode="browse")
        scrollbar.config(command=new_customer_lb.yview)
        new_customer_lb.pack()


    def buttons(self):
        load = Button(self, text='show customers', command=lambda:self.load_working_customers())
        test = Button(self, text='test new colors', command=lambda:self.test_colors())
        load.pack()
        test.pack()

    def load_working_customers(self):
        new_customer_lb.delete(*new_customer_lb.get_children())
        for a in range(0,10):            
            new_customer_lb.insert('','end', values=(a,'first','last'))

    def test_colors(self):
        new_customer_lb.delete(*new_customer_lb.get_children())                 

        new_customer_lb.tag_configure("evenrow",background='white',foreground='black')
        new_customer_lb.tag_configure("oddrow",background='black',foreground='white')
        for a in range(0,10):            
            if a % 2 == 0:
                new_customer_lb.insert('','end', values=(a,'first','last'), tags=('evenrow',))
            if a % 2 != 0:
                new_customer_lb.insert('','end', values=(a,'first','last'), tags=('oddrow',))

root = Tk()
app = Test()
app.mainloop()

This is to create a SQL db.这是为了创建一个 SQL 数据库。 then loads the few customers from db into listbox.然后将少数客户从 db 加载到列表框中。 then you can click test new colors button to show it changing colors for odd rows.然后您可以单击测试新颜色按钮以显示它更改奇数行的颜色。 this is runnable as long as you have sqlalchemy installed as module.只要您将 sqlalchemy 安装为模块,它就可以运行。

from Tkinter import *
import ttk
from sqlalchemy import Column, ForeignKey, Integer, String, Text
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import relationship
from sqlalchemy import create_engine
from sqlalchemy.orm import sessionmaker

base = declarative_base()


class Customer(base):
    __tablename__='Customer_Details'
    Id = Column(Integer, primary_key=True)
    first_name = Column(String(64))
    last_name = Column(String(64))


class DB_connection(object):
    def __enter__(variable):
        variable.engine = create_engine("sqlite:///example.db")
        base.metadata.bind = variable.engine
        variable.DBSession = sessionmaker(bind=variable.engine)
        variable.Session = variable.DBSession
        variable.session = variable.Session()
        return variable
    def __exit__(variable, exc_type, exc_val, exc_tb):
        variable.session.commit()
        variable.session.close()

class Test(Frame):

    def __init__(self):
        Frame.__init__(self)
        self.pack()
        self.listbox()
        self.buttons()

    def listbox(self):
        global new_customer_lb

        scrollbar = Scrollbar(self, orient="vertical")
        new_customer_lb = ttk.Treeview(self, columns=('ID','First Name','Last Name'))
        new_customer_lb['show']='headings'
        new_customer_lb.heading('#1', text= 'ID')
        new_customer_lb.column('#1', width=50, stretch=NO)
        new_customer_lb.heading('#2', text= 'First Name')
        new_customer_lb.column('#2', width=100, stretch=NO)
        new_customer_lb.heading('#3', text= 'Last Name')
        new_customer_lb.column('#3', width=100, stretch=NO)
        new_customer_lb.configure(yscroll = scrollbar.set, selectmode="browse")
        scrollbar.config(command=new_customer_lb.yview)
        new_customer_lb.pack()


    def buttons(self):
        db = Button(self, text='make DB', command=lambda:self.create_db())
        customer = Button(self, text='create customers', command=lambda:self.create_customers())
        load = Button(self, text='show customers', command=lambda:self.load_working_customers())
        test = Button(self, text='test new colors', command=lambda:self.test_colors())
        db.pack()
        customer.pack()
        load.pack()
        test.pack()

    def create_db(self):
        print("start create db function")
        engine = create_engine('sqlite:///example.db')
        base.metadata.create_all(engine)
        print("Success create db function")

    def create_customers(self):
        print ('Start add customer sql')
        customer1 = Customer(first_name='first1',last_name='last1')
        customer2 = Customer(first_name='first2',last_name='last2')
        customer3 = Customer(first_name='first3',last_name='last3')
        customer4 = Customer(first_name='first4',last_name='last4')
        with DB_connection() as DB:
            DB.session.add_all([customer1,customer2,customer3,customer4])
        print ('sucess add customer sql')

    def load_working_customers(self):
        new_customer_lb.delete(*new_customer_lb.get_children())    
        with DB_connection() as DB:
            for a,b,c in DB.session.query(Customer.Id,Customer.first_name,Customer.last_name).order_by(Customer.Id):
                new_customer_lb.insert('','end', values=(a,b,c))

    def test_colors(self):
        new_customer_lb.delete(*new_customer_lb.get_children())                 

### configure even and odd here
        new_customer_lb.tag_configure("evenrow",background='white',foreground='black')
        new_customer_lb.tag_configure("oddrow",background='black',foreground='white')

        with DB_connection() as DB:
## this loop will take 'a' (Customer.Id) and test if even or odd
            for a,b,c in DB.session.query(Customer.Id,Customer.first_name,Customer.last_name).order_by(Customer.Id):                
                if a % 2 == 0:
                    new_customer_lb.insert('','end', values=(a,b,c), tags=('evenrow',))
                else:
                    new_customer_lb.insert('','end', values=(a,b,c), tags=('oddrow',))

root = Tk()
app = Test()
app.mainloop()

working code: python3.6工作代码:python3.6

try:
    from Tkinter import *
    from ttk import *
except ImportError:  # Python 3
    from tkinter import *
    from tkinter.ttk import *

class App(Frame):

    def __init__(self, parent):
        Frame.__init__(self, parent)
        self.CreateUI()
        self.LoadTable()
        self.grid(sticky = (N,S,W,E))
        parent.grid_rowconfigure(0, weight = 1)
        parent.grid_columnconfigure(0, weight = 1)

    def CreateUI(self):
        style = Style(self)
        
        style.theme_use("clam")
        style.configure("Treeview.Heading", background="black", foreground="white")        
        
        style.configure("Treeview",
                        background = "silver",
                        foreground = "black",
                        rowheight = 25,
                        fieldbackground = "silver",                
                        )
        style.map('Treeview', background=[('selected', 'green')])

        
        tv = Treeview(self)
        tv['columns'] = ('filename', 'environment', 'status')
        tv.heading("#0", text='Job Id')
        tv.column("#0", anchor="w", width=100)
        tv.heading('filename', text='File Name')
        tv.column('filename', anchor='w')
        tv.heading('environment', text='Environment')
        tv.column('environment', anchor='w', width=100)
        tv.heading('status', text='Status')
        tv.column('status', anchor='w', width=100)        
        tv.grid(sticky = (N,S,W,E))
        self.treeview = tv
        self.grid_rowconfigure(0, weight = 1)
        self.grid_columnconfigure(0, weight = 1)
        
        

    def LoadTable(self):
        self.treeview.tag_configure('oddrow', background = "#D3D3D3")
        self.treeview.tag_configure('evenrow', background = "#000000")
        self.treeview.insert('', 'end', text="First", iid=0,values=('10:00',
                             '10:10', 'Ok'), tags=('oddrow'))
        
        self.treeview.insert('', 'end', text="First", iid=1,values=('10:00',
                             '10:10', 'Ok'), tags=('evenrow'))

def main():
    root = Tk()
    App(root)
    root.mainloop()

if __name__ == '__main__':
    main()

I made a function that applies alternating row color.我制作了一个应用交替行颜色的 function。 This is a better way for those who are resorting the rows and need to recolor correctly again.对于那些正在重新排序行并需要再次正确重新着色的人来说,这是一种更好的方法。

def apply_striped_row_color(tv, oddcolor='lightgray', evencolor='white'):
    for index, iid in enumerate(tv.get_children()):
        tags = tv.item(iid,'tags')  # get current tags
        tags.remove('evenrow') if 'evenrow' in tags else None  # remove if exist
        tags.remove('oddrow') if 'oddrow' in tags else None  # remove if exist
        tags.append('evenrow' if index%2 else 'oddrow')
        self.item(iid, tags=tags)
    tv.tag_configure('oddrow', background=oddcolor)
    tv.tag_configure('evenrow', background= evencolor)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM