質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

Tkinter

Tkinterは、GUIツールキットである“Tk”をPythonから利用できるようにした標準ライブラリである。

Q&A

解決済

1回答

1487閲覧

Python3 Tkinter ソート後の背景色変更

person

総合スコア223

Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

Tkinter

Tkinterは、GUIツールキットである“Tk”をPythonから利用できるようにした標準ライブラリである。

0グッド

1クリップ

投稿2021/08/31 06:57

TkinterのTreeview(Headings)で偶数行目と奇数行目で色を分けました。
ヘッダをクリックすると、そのデータを名前で昇順降順ソートします。

ソート後に、背景色が偶数行目と奇数行目で分けられていないため、再度色設定をしたいのですがtagsの再設定の方法が分かりません。
headerSelected()にあるソート時のforの中にtags設定処理を追加すればできそうな気がするのですが・・・方法も合っているか含めて回答お願いします。

Python

1from tkinter import ttk 2from tkinter.font import Font 3import tkinter as tk 4 5 6def fixed_map(option): 7 # https://www.it-swarm-ja.com/ja/python/tkinter-ttk-treeview%E8%89%B2%E4%BB%98%E3%81%8D%E3%81%AE%E8%A1%8C/815083360/ 8 9 return [elm for elm in style.map('Treeview', query_opt=option) if 10 elm[:2] != ('!disabled', '!selected')] 11 12 13def headerSelected(tree, reverse_flag): 14 15 # http://notwodaily.hatenablog.com/entry/2018/06/15/003411 16 x = tree.winfo_pointerx() - tree.winfo_rootx() 17 select_column_str = tree.identify_column(x) 18 select_column_int = int(select_column_str[1:]) - 1 19 20 21 #https://stackoverrun.com/ja/q/396512 22 l = [(tree.set(k, select_column_int), k) for k in tree.get_children("")] 23 l.sort(reverse=reverse_flag) 24 25 for index, (val, k) in enumerate(l): 26 tree.move(k, "", index) 27 # ここの繰り返し処理で色分けできそうだが指定方法が分からない 28 29 tree.heading(select_column_int, command=lambda:headerSelected(tree, not reverse_flag)) 30 31 32win = tk.Tk() 33 34win.rowconfigure(0, weight=1) 35win.columnconfigure(0, weight=1) 36 37win.tk.eval(""" 38 ttk::style map Treeview \ 39 -foreground {disabled SystemGrayText \ 40 selected SystemHighlightText} \ 41 -background {disabled SystemButtonFace \ 42 selected SystemHighlight} 43 """) 44 45style = ttk.Style() 46fontsize = 30 47myfont = Font(size=fontsize) 48style.configure("Treeview.Heading", font=("", fontsize)) 49style.configure("Treeview", font=("", fontsize), 50 rowheight=myfont.metrics()["linespace"]) 51style.configure("Vertical.TScrollbar", arrowsize=30) 52 53 54datas = [ 55 ["aaa", "kkk", "hhh"], 56 ["bbb", "eee", "fff"], 57 ["ggg", "jjj", "eee"], 58 ["ddd", "lll", "iii"], 59] 60 61columns = 0 62for data in datas: 63 if columns < len(data): 64 columns = len(data) 65 66 67style.map("Treeview", foreground=fixed_map("foreground"), background=fixed_map("background")) 68 69tree = ttk.Treeview(win) 70tree.grid(row=0, column=0, sticky="nsew", padx=(5, 0), pady=(5, 5)) 71tree["columns"] = tuple(range(columns)) 72tree["show"] = "headings" 73for i in range(columns): 74 tree.heading(i, text="Data"+str(i+1), command=lambda:headerSelected(tree, False)) 75for i, data in enumerate(datas): 76 if i % 2 == 0: 77 tree.insert("", "end", value=(data), tags="even") 78 else: 79 tree.insert("", "end", value=(data), tags="odd") 80 81tree.tag_configure("even", background="lightgray") 82tree.tag_configure("odd", background="darkgray") 83 84ysb = ttk.Scrollbar(win, orient="vertical", command=tree.yview) 85tree.configure(yscrollcommand=ysb.set) 86ysb.grid(row=0, column=1, sticky="nsew", padx=(0, 5), pady=5) 87 88 89win.mainloop()

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

簡単な方法は、一度要素を削除してから新たにinsert する方法です。
insert している部分を関数化して、ソート済みデータを渡すようにします。

別のタグを引き継ぎたい為、削除・新規追加ではなく、
移動で実装したい場合は、既存のタグを所得し、odd/even のみを再設定します。
(他のタグを併用している場合は、既存のタグの移動も必要な点に注意)

odd/evenの管理は集合型を使うと簡潔に表現できます。

# 元のタグ - 削除するタグ | 追加するタグ >>> {"odd"} - {"odd"} | {"even"} {"even"} >>> {"even"} - {"odd"} | {"even"} {"even"} # 他のタグが含まれている場合でも可 >>> {"AAA", "odd"} - {"odd"} | {"even"} {"AAA", "even"}

リストで管理する場合、

  • even の場合、(既存のタグにodd が含まれていれば削除してから) even を追加
  • odd の場合、(既存のタグにevenが含まれていれば削除してから) odd を追加

といった複数の文で処理したりする所を、
集合を使うと 元のタグの集合 - 削除するタグの集合 | 追加するタグの集合 といった "式" で表現できます。

# ここの繰り返し処理で色分けできそうだが指定方法が分からない # 既存のタグを所得して、集合型(set)に変換 tags = set(tree.item(k)["tags"]) # 削除するタグ・追加するタグを得る # TIPS: スライスの利用による昇順降順 [1,2][::-1] => [2,1] diff, add = [{"even"}, {"odd"}][::(1 if index%2 else -1)] # タグを再設定 tree.item(k, tags=list(tags - diff | add))

投稿2021/08/31 12:43

編集2021/08/31 14:09
teamikl

総合スコア8664

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

person

2021/09/01 05:23

回答ありがとうございます。 質問した後で申し訳ないのですが、ソート機能に欠陥(?)が見つかったので、もしかしたら回答以外の方法で対処する必要が出てきてしまうかもしれません・・・。 上記の問題については、別途質問しました。 https://teratail.com/questions/357207
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問