ttk 树视图:交替行颜色

发布于 2024-12-11 09:04:22 字数 124 浏览 0 评论 0原文

如何为 treeview 小部件设置样式,以便交替行具有不同的背景颜色,例如,第 1,3,5 行具有白色背景,第 2,4,6 行具有浅蓝灰色背景?

我还想设置网格线

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?

I'd also like to set gridlines.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(7

向地狱狂奔 2024-12-18 09:04:22

几个月前我也遇到了同样的问题。

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.

基本上,您将一个标签应用于所有奇数行,另一个标签应用于每个偶数行,然后配置标签。


当您在树视图中创建项目时,向它们添加标签:

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

此代码在 tree 中创建一个元素,并且 tags 参数将标签“oddrow”分配给该元素。

使用“奇数行”和“偶数行”标签创建所有元素后,您可以为标签着色:

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

I had this same issue a few months ago.

From the tk docs:

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.

Once you've created all your elements with 'oddrow' and 'evenrow' tags, you can color the tags:

tree.tag_configure('oddrow', background='orange')
tree.tag_configure('evenrow', background='purple')
南烟 2024-12-18 09:04:22

我意识到这是一个老问题,但仅用于在创建树后配置标签的记录(即尚未添加任何项目时)也可以。当项目稍后插入时,它们将被赋予适合其“奇数行”或“偶数行”标签的背景颜色。

I realise this is an old question but just for the record configuring the tags just after creating the tree (i.e. 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.

剩余の解释 2024-12-18 09:04:22

这是无需任何额外模块即可运行的...可能会弄乱代码以使其与您自己的代码一起使用。

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 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()
今天小雨转甜 2024-12-18 09:04:22

这是为了创建一个 SQL 数据库。然后将数据库中的少数客户加载到列表框中。
然后您可以单击“测试新颜色”按钮以显示奇数行的颜色变化。只要您将 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()

This is to create a SQL db. then loads the few customers from db into listbox.
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.

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()
心在旅行 2024-12-18 09:04:22

工作代码: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()

working code: 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()
梦魇绽荼蘼 2024-12-18 09:04:22

我制作了一个应用交替行颜色的函数。对于那些重新排列行并需要再次正确重新着色的人来说,这是一个更好的方法。

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)

I made a function that applies alternating row color. 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)
情绪操控生活 2024-12-18 09:04:22

我对其进行了更好的更新,这适用于更高版本的 python 3.9+,也许更旧。

这将进行排序,您只需在函数中添加对它的调用即可更新您的树视图以及底部的排序函数,并且它将在排序后保留它。

def apply_striped_row_color(tree, oddcolor='lightgray', evencolor='white'):
for index, iid in enumerate(tree.get_children()):
    if index % 2 == 0:
        tree.item(iid, tags=('evenrow',))
    else:
        tree.item(iid, tags=('oddrow',))
tree.tag_configure('oddrow', background=oddcolor)
tree.tag_configure('evenrow', background=evencolor)

I updated it a little bit better, and this is working with later versions of python 3.9+, maybe older.

This will sort and you can just ad the call to it in your function to update your treeview as well as your sort function at the base and it will keep it after sorting.

def apply_striped_row_color(tree, oddcolor='lightgray', evencolor='white'):
for index, iid in enumerate(tree.get_children()):
    if index % 2 == 0:
        tree.item(iid, tags=('evenrow',))
    else:
        tree.item(iid, tags=('oddrow',))
tree.tag_configure('oddrow', background=oddcolor)
tree.tag_configure('evenrow', background=evencolor)
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文