64097


ttk.Treeview
に表示したリストに、見やすいように偶数/奇数行でbackground色を変更したり、特定の条件のときにグレーハッチするような動作をさせていました。

新しく開発環境を構築した際、インストーラの公開の関係上、Python3.7を導入しました。  
Python3.6では正常にbackground色を変更できます。  
Python3.7ではbackground色を変更できません  
同じソースコードで、Python3.6とPython3.7で挙動が異なります。  
以下にミニマムなソースを示します。

Python3.7以降で正常にリストを色分けするにどのようにしたらよいのでしょうか？

[code]

    import tkinter as tk
    
    from tkinter import ttk
    
    if __name__ == '__main__':
        obj = ttk.tkinter.Tk()
    
        tree = ttk.Treeview(
            obj,
            show = "headings",
            )
    
        tree_item = {
            "No.":40,
            "Name":80,
        }
    
        tree["columns"]=tuple(range(1,len(tree_item)+1))
    
        for i, item in enumerate(tree_item.items()):
            name, width = item
            tree.heading(i+1,text=name)
            tree.column(i+1,minwidth = width, width = width, stretch = False, anchor = tk.CENTER)
    
        value_list = [
            'aaa','bbb','ccc',
        ]
    
        for i,v in enumerate(value_list):
            tree.insert("",index = "end",tags = i,value=[i+1,v])
            if i%2 == 0:
                tree.tag_configure(i,background = 'yellow')
    
        tree.pack()
    
        obj.mainloop()
    
[/code]


CC BY-SA 4.0
2020-03-25T01:24:07.687
64095
2020-03-25T02:43:11.500
2020-03-25T02:43:11.500
3060
32891
question
python python3 tkinter
Python ttk.Treeview python3.7でリストに割り当てたtagに対して色を設定する方法


おそらくこれらの記事が該当するでしょう。  
Python 3.7.3 以後の tkinter に入ったバグのようです。

[python : tkinter treeview colors are not
updating](https://stackoverflow.com/q/56331001/9014308)  
[Tkinter Treeview issue when inserting rows with
tags](https://stackoverflow.com/q/55844576/9014308)

> Looks like the issue was caused by a newer version of tkinter, not a newer
> version of Python. This was reported in <https://bugs.python.org/issue36468>
> and <https://core.tcl-lang.org/tk/info/509cafafae>  
>  Here is a proposed solution. It should be both backward and forward
> compatible:
>
> この問題は、Python の新しいバージョンではなく、tkinter の新しいバージョンが原因のようです。これは
> <https://bugs.python.org/issue36468> と <https://core.tcl-
> lang.org/tk/info/509cafafae> で報告されています。  
>  ここに提案された解決策があります。それは、後方互換性と前方互換性の両方を持っている必要があります。
[code]

>     def fixed_map(option):
>         # Fix for setting text colour for Tkinter 8.6.9
>         # From: https://core.tcl.tk/tk/info/509cafafae
>         #
>         # Returns the style map for 'option' with any styles starting with
>         # ('!disabled', '!selected', ...) filtered out.
>  
>         # style.map() returns an empty list for missing options, so this
>         # should be future-safe.
>         return [elm for elm in style.map('Treeview', query_opt=option) if
>             elm[:2] != ('!disabled', '!selected')]
>  
>     style = ttk.Style()
>     style.map('Treeview', foreground=fixed_map('foreground'),
> background=fixed_map('background'))
>  
[/code]

上記を質問記事のソースに適用したら、それらしい動作になるようです。  
項目数は増やしてみました。

[code]

    import tkinter as tk
    
    from tkinter import ttk
    
    def fixed_map(option):
        # Fix for setting text colour for Tkinter 8.6.9
        # From: https://core.tcl.tk/tk/info/509cafafae
        #
        # Returns the style map for 'option' with any styles starting with
        # ('!disabled', '!selected', ...) filtered out.
    
        # style.map() returns an empty list for missing options, so this
        # should be future-safe.
        return [elm for elm in style.map('Treeview', query_opt=option) if
            elm[:2] != ('!disabled', '!selected')]
    
    if __name__ == '__main__':
        obj = ttk.tkinter.Tk()
    
        style = ttk.Style()  
        style.map('Treeview', foreground=fixed_map('foreground'), background=fixed_map('background'))
    
        tree = ttk.Treeview(
            obj,
            show = "headings",
            )
    
        tree_item = {
            "No.":40,
            "Name":80,
        }
    
        tree["columns"]=tuple(range(1,len(tree_item)+1))
    
        for i, item in enumerate(tree_item.items()):
            name, width = item
            tree.heading(i+1,text=name)
            tree.column(i+1,minwidth = width, width = width, stretch = False, anchor = tk.CENTER)
    
        value_list = [
            'aaa','bbb','ccc','ddd','eee','fff',
        ]
    
        for i,v in enumerate(value_list):
            tree.insert("",index = "end",tags = i,value=[i+1,v])
            if i%2 == 0:
                tree.tag_configure(i,background = 'yellow')
    
        tree.pack()
    
        obj.mainloop()
    
[/code]

Python 3.8.2 で以下のようになりました。  
[![tkinter対応結果](https://i.stack.imgur.com/K0Hdp.png)](https://i.stack.imgur.com/K0Hdp.png)


CC BY-SA 4.0
2020-03-25T02:03:27.727
64097
2020-03-25T02:03:27.727
26370
64095
answer