

現在、あるアラートメールを受信して本文だけをリスト表示するプログラムをpythonとtkinterを使用して作成しています。もともとexcel
vbaで作っていたものをpython版でアップデートしようとしているのですが、そのリスト表示にlistboxウイジットを使用しています。excel
vbaの時はlistviewを使用していました。

メールを受信してリスト表示するところまではできているのですが、その中で、特に注意すべきメールはその行だけ赤く色を変えて太字で強調したいのですが、なかなかうまくできません。そもそもlistboxはそういったことができないのではとさえ思っていて、そのあたりをわかる方いましたらご教示いただけるとありがたいです。


CC BY-SA 4.0
2020-06-04T02:08:34.697
67271
2020-06-04T07:50:50.397
40471
question
python tkinter
pythonを使ったtkinterのlistboxウィジットの一行だけ赤字、強調表示にしたい


こちらの記事で対応方法を答えています。  
いずれも同じで[itemconfig()](http://effbot.org/tkinterbook/listbox.htm#Tkinter.Listbox.itemconfig-
method)で位置と変更内容を指定するものです。

[Is it possible to colour a specific item in a Listbox
widget?](https://stackoverflow.com/q/5348454/9014308)  
ちなみにこちらは 2.x系 [Changing colour of item in Tkinter
listbox](https://stackoverflow.com/q/36914176/9014308)

最初の記事を引用すると以下になります。

> According to the `effbot.org` documentation regarding the
> [`Listbox`](http://effbot.org/tkinterbook/listbox.htm#Tkinter.Listbox)
> widget you cannot change the color of spefic items:  
>  Listboxウィジェットに関するeffbot.orgのドキュメントによると、特定のアイテムの色は変更できません。
>

>> The listbox can only contain text items, and all items must have the same
font and color  
>  リストボックスにはテキストアイテムのみを含めることができ、すべてのアイテムは同じフォントと色である必要があります
>
> But actually you can change both the font and background colors of specific
> items, by using the
> [`itemconfig`](http://effbot.org/tkinterbook/listbox.htm#Tkinter.Listbox.itemconfig-
> method) method of your `Listbox` object. See the following example:  
>  ただし、実際には、Listboxオブジェクトのitemconfigメソッドを使用して、特定のアイテムのフォントと背景色の両方を変更できます。
> 次の例を参照してください。
[code]

>     import tkinter as tk
>  
>     def demo(master):
>         listbox = tk.Listbox(master)
>         listbox.pack(expand=1, fill="both")
>  
>         # inserting some items
>         listbox.insert("end", "A list item")
>  
>         for item in ["one", "two", "three", "four"]:
>             listbox.insert("end", item)
>  
>         # this changes the background colour of the 2nd item
>         listbox.itemconfig(1, {'bg':'red'})
>  
>         # this changes the font color of the 4th item
>         listbox.itemconfig(3, {'fg': 'blue'})
>  
>         # another way to pass the colour
>         listbox.itemconfig(2, bg='green')
>         listbox.itemconfig(0, foreground="purple")
>  
>     if __name__ == "__main__":
>         root = tk.Tk()
>         demo(root)
>         root.mainloop()
>  
[/code]

上記の実行結果が以下になります。  
ここから行を選択すると、それは青い背景の行になりますが。  
[![tkinter list
color](https://i.stack.imgur.com/i0JXT.png)](https://i.stack.imgur.com/i0JXT.png)

* * *

`listbox`では文字色/背景色は変えられても、特定行のフォントや太字化は出来ないようですね。  
[How to change font to bold/underline/italics in Python Tkinter
listbox?](https://stackoverflow.com/q/53560889/9014308)

> You cannot change the font of an individual item in a listbox.  
>  If you need something that works like a listbox but which offers the
> ability to change the font of individual items, you can use the
> `ttk.Treeview` widget.
>
> リストボックス内の個々のアイテムのフォントを変更することはできません。  
>
> リストボックスのように機能するが、個々のアイテムのフォントを変更する機能を提供するものが必要な場合は、ttk.Treeviewウィジェットを使用できます。

ということで、この辺の記事でttk.Treeviewのフォントを変えています。  
[Python tkinter single label with bold and normal
text](https://stackoverflow.com/q/40237671/9014308)  
[ttk.Treeview - Can't change row
height](https://stackoverflow.com/q/26957845/9014308)

ただしttk.Treeviewウィジェットも使用には注意が必要です。  
以下にフォント処理を追加してみました。  
[Python ttk.Treeview
python3.7でリストに割り当てたtagに対して色を設定する方法](https://ja.stackoverflow.com/q/64095/26370)  
`#`1個だけの部分が注意、`####`と4つの部分がフォント処理

[code]

    import tkinter as tk
    from tkinter import ttk
    
    # 以下関数が対処のための処理
    def fixed_map(option):
        return [elm for elm in style.map('Treeview', query_opt=option) if
            elm[:2] != ('!disabled', '!selected')]
    
    if __name__ == '__main__':
        obj = ttk.tkinter.Tk()
    
        # 以下2行が対処の必要な処理 & 上記関数を呼んでいる
        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') # ここで色を変えている
    
            #### 以下がフォントを変えている部分。上記と組み合わせて1回の呼び出しで両方変えても良い。
            if i == 2:
                tree.tag_configure(i,font = 'Arial 16 bold')
            else:
                tree.tag_configure(i,font = 'Courier 16')
    
        tree.pack()
        obj.mainloop()
    
[/code]

こんな結果になります。  
[![color and
bold](https://i.stack.imgur.com/RoF9O.png)](https://i.stack.imgur.com/RoF9O.png)


CC BY-SA 4.0
2020-06-04T03:22:01.680
67274
2020-06-04T07:50:50.397
2020-06-17T08:14:45.997
-1
26370
67271
answer