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

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

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

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

Tkinter

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

Q&A

解決済

2回答

14559閲覧

Python3 Tkinter treeviewのデータの更新

person

総合スコア224

Python 3.x

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

Tkinter

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

1グッド

2クリップ

投稿2020/11/11 12:32

編集2020/11/11 23:46

TkinterのTreeviewでデータの一部を変更することは可能ですか?

例えば、下のコードだと

aaa, bbb, ccc

とある場合

aaa, ddd, ccc

のようにしたいです。

全データを控えた後に全行消して、一部を変更して再表示する方法を考えたのですが、
下のidを使ってn列目のデータを変更するといったことは可能でしょうか?

回答よろしくおねがいします。

Python

1from tkinter import ttk 2import tkinter as tk 3 4if __name__ == "__main__": 5 win = tk.Tk() 6 win.geometry("500x400") 7 8 # 幅取得 9 win.update_idletasks() # winfo_width() の戻り値 1 回避 10 win_width = win.winfo_width() 11 12 # 引き伸ばし 13 win.rowconfigure(0, weight=1) 14 win.columnconfigure(0, weight=1) 15 16 # スタイル_テーマ 17 s = ttk.Style() 18 s.theme_use("clam") 19 20 tree = ttk.Treeview(win) 21 # 列数 22 tree["columns"] = (1, 2, 3) 23 tree["show"] = "headings" 24 # 列幅指定 25 tree.column(1, width=int(win_width/3)) 26 tree.column(2, width=int(win_width/3)) 27 tree.column(3, width=int(win_width / 3)) 28 # ヘッダ 29 tree.heading(1, text="Data1") 30 tree.heading(2, text="Data2") 31 tree.heading(3, text="Data3") 32 tree.grid(row=0, column=0, sticky="nsew") 33 34 # インサート 35 id = tree.insert("", "end", value=["aaa", "bbb", "ccc"]) 36 print(id) 37 38 win.mainloop() 39
oyakata0702👍を押しています

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

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

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

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

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

q_sane_q

2020/11/11 13:57 編集

これはTreeviewの特定の行/特定の列の値を後から変更したい、ということでいいのでしょうか? 質問のデータ例の上は「,」で区切られているのに下はそうなっていないのは変更前後で何か違いがあるからでしょうか
person

2020/11/13 01:52 編集

記載ミスです。 カンマは列を区別するためにつけたのですが、あとのほうはつけ忘れました。 修正しました。
guest

回答2

0

ベストアンサー

変更が一カ所のみの場合

python

1 tree.set(id, 2, "ddd")

set(item, column=None, value=None)¶

  • 1 引数で呼び出された場合、指定された item のカラムと値のペアからなる辞書を返します。
  • 2 引数で呼び出された場合、指定された column の現在の値を返します。
  • 3 引数で呼び出された場合、与えられた item の column を指定された値 value に設定します。

注意点: column は、n 列目の数値ではなく
tree["columns"] = (1, 2, 3) で指定した任意の名前です。
このコードでは column名==列数になっていますが、column名が文字の場合
n 列目を指定する column 名は tree["columns"][n-1]

訂正: 整数指定出来ました。

columns オプションのリストにある名前。
n 番目のデータカラムを指し示す整数 n 。
n を整数として n 番目の表示されているカラムを指し示す #n という形式の文字列。

要素のオプション値は実際に格納されている順序とは違った順序で表示されることがあります。
show="tree" が指定されていない場合でも、カラム #0 は常にツリーカラムを指しています。

投稿2020/11/11 16:11

編集2020/11/11 16:39
teamikl

総合スコア8760

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

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

q_sane_q

2020/11/11 16:26

確かに中身を舐めたりせず変更するだけなので、setで挿げ替えた方が楽ですね。(カラム指定は実際よく間違える) カラム指定を「0, 1, 2……」と位置で指定したいときもあります…
teamikl

2020/11/11 17:09 編集

カラム指定についての注意点の記載、 マニュアルを確認したら間違えてたので訂正しました。 ※ 追記: ↓間違い。1開始なのは ["columns"] = (1, 2, 3) だった為 0番目はツリーのルートカラムなので、values=のカラム値は1開始になるみたいです なので、0開始で数える場合は tree["columns"]を参照することに。 https://docs.python.org/ja/3/library/tkinter.ttk.html#item-options
teamikl

2020/11/11 16:51 編集

位置指定は、カラムの順序を変えた場合 & 今回の様にカラムの識別子が数値の場合は、特に注意が必要で tree["columns"] = (1, 2, 3) ... tree["columns"] = (1, 3, 2) tree.set(id, 2, "ddd") では、カラムとしての値が優先されて3列目の値が変更されました。 # 2列目を変更する。 tree.set(id, tree["column"][2-1], "ddd")
q_sane_q

2020/11/11 16:56

あー…… これ、こんな書き方やったことなかった(大体機械的に1、2、3……で使ってた)ので気付かなかったんですがsetのcolumnに整数を渡すと『columns オプションのリストにある名前』が優先で探し、なかったら『(0開始で)n 番目のデータカラム』を探しに行くんですかね tree["columns"] = (2, 3, 4) だと0と2が同じ列を指しますね。
teamikl

2020/11/11 17:31 編集

上記URLのカラム識別子の項目より。 >データカラムを指す数字は、要素の values オプションのリストのインデックスです 3個上の私のコメントが間違ってました。 間違い: ~~>0番目はツリーのルートカラムなので、values=のカラム値は1開始になるみたいです~~ - "#0" がルートカラム - 数値の0 は(カラム識別子に存在しなければ) valuesのインデックス。
teamikl

2020/11/12 00:12 編集

実際は、見た目の n 列目を変えたい場合はあまりなく、 内部のデータの n 列目を変えたいことの方が多いはずなので、 tree.set(id, tree["column"][2-1], "ddd") のような書き方は、実際には使わないと思いますが、 思わぬところではまってしまった。 対策: カラム識別子を文字にする。インデックス指定の場合"#n" 形式で明示。 ---- tree["columns"] = (1, 2, 3) tree.set(id, 2, "ddd") このコードの問題点: columns 識別子に変更があった際 識別子指定だったのが、values のインデックス指定になり、 動作が変わってしまう。
guest

0

とりあえずそういうことだということで回答します

以下のようにタプルを取り出して作り直し、入れ直せばそのように動くと思います

Python

1 temp = tree.item(id, "values") 2 temp = (temp[0], "ddd", temp[2]) 3 tree.item(id, values=temp)

ただ、列数が3つならいいのですがもっと多くなったりするとタプルの作り替えが面倒なので、スライスと展開を使って

Python

1 temp = tree.item(id, "values") 2 temp = (*temp[:1], "ddd", *temp[2:]) 3 tree.item(id, values=temp)

と書いておくといいのかもしれません。

後から特定の行を指定するなら↓です。

Python

1 target = tree.get_children()[0] # 1行目の場合 2 temp = tree.item(target, "values") 3 temp = (*temp[:1], "ddd", *temp[2:]) 4 tree.item(target, values=temp)

投稿2020/11/11 15:25

q_sane_q

総合スコア610

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.35%

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

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

質問する

関連した質問