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

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

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

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

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

Q&A

解決済

1回答

3007閲覧

Tkinterでのデスクトップアプリ開発において、表のカラム固定の方法がわからない

Tera0724

総合スコア18

Tkinter

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

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

0グッド

0クリップ

投稿2021/10/25 05:52

現在、Tkinterを使用したデスクトップアプリの開発を行っています。その中で、treeViewを使用した表出力の部分があります。表について、横スクロール機能をつけているのですが、特定の列(前3列ほど)を固定したいと考えています。しかし、固定方法について調べても見つけることができなてい状態です。
横スクロール時の列固定について参考になりそうな資料等教えていただけると助かります。よろしくお願いします。
コードと実現させたいイメージは以下の通りです。よろしくお願いします。

def show_table(data_table, root, num_of_add_column): tree1 = ttk1.Treeview(root) columns = [1, 2, 3, 4] for i in range(num_of_add_column): columns.append(i + 5) tree1["columns"] = tuple(columns) # columns tree1["show"] = "headings" # normal table tree1.column(1, width=50) # width of column tree1.column(2, width=200) tree1.column(3, width=100) tree1.column(4, width=100) for i in range(num_of_add_column): tree1.column(i+5, width=120) tree1.heading(1, text="ID") # header index tree1.heading(2, text="name") tree1.heading(3, text="latitude") tree1.heading(4, text="longitude") for i in range(num_of_add_column): tree1.heading(i + 5, text="point_" + str(i)) for i in range(len(data_table)): id = data_table["id"].iloc[i] name = data_table["name"].iloc[i] latitude = data_table["latitude"].iloc[i] longitude = data_table["longitude"].iloc[i] values = [id, name, latitude, longitude] for j in range(num_of_add_column): distance = data_table["point_" + str(j)].iloc[i] values.append(distance) tree1.insert("", "end", tag=0, values=values) vbar1 = ttk1.Scrollbar(root, orient=tkinter.VERTICAL, command=tree1.yview) vbar1.pack(side = tk1.LEFT, fill = tk1.Y) vbar1.place(x=590, y=140, height=300) vbar2 = ttk1.Scrollbar(root, orient=tkinter.HORIZONTAL, command=tree1.xview) vbar2.pack(side = tk1.BOTTOM, fill = tk1.X) vbar2.place(x=40, y=435, width=550) tree1.configure(yscrollcommand = vbar1.set, xscrollcommand = vbar2.set) tree1.pack(side = tk1.LEFT) tree1.place(x=40, y=140, width=550, height=300)

イメージ説明

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

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

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

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

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

guest

回答1

0

ベストアンサー

残念ながら ttk.Treeview ウィジェットに列・行を固定化する機能はありません。

(A) 疑似的に実装するには、Treeview を2つ使い、
表示内容を同期する事になります。

実装方法のヒント:

  • ウィジェットは同じ位置に重ね合わせて配置が可能 (lift, lower)
  • 固定列として表示するウィジェットは縦スクロールのみ追従

 横スクロール時は、下に配置されたテーブルのみスクロールし、
上に配置されたテーブルはスクロールせずに固定列になる。

  • テーブルの表示行を同期する為、必要に応じてスクロール時の処理を追加

 縦スクロールバーを動かした時、テーブル内でカーソル移動した時、行を選択した時、等。

単一の Treeview で実装したい場合は、
(B) スクロールバーのイベントで、スクロール位置に応じて
Treeview の見せ方を工夫する等の方法が考えられます。

実装方法(概要のみ): スクロール位置から表示位置を計算し、
固定列が画面の端に表示されるように、columns の順序や列幅を再計算。

※ 「疑似的に」とした理由は、実装方法により操作にラグが発生する事があります。


関連 (外部ライブラリ、他のGUIライブラリ)

  • TkinterEP table github ... 未対応
  • tkintertable github ... 未対応
  • pandastable github ... 未対応
  • PyQt/PySide ... QTableView

 Qt の実装例ですが、2つのウィジェットを同期させて表示する方法(C++言語)
https://doc.qt.io/qt-5/qtwidgets-itemviews-frozencolumn-example.html

  • wxPython ... wx.grid.Grid FreezeTo メソッド

 wxPythonの Grid では row, col 指定だけで簡単に実現できます。
https://github.com/wxWidgets/wxWidgets/blob/master/src/generic/grid.cpp
該当箇所(C++言語): FreezeTo(), InitializeFrozenWindows() 内部では (A) と同じような実装方法

  • tcl/tk には tktable というテーブル用の外部ライブラリがあり
    titlerows, titlecols オプションで固定化する行列数を設定できます。
    Tkinter で、tcl/tk のライブラリを読み込む事で利用はできますが、
    Python のライブラリとしては整備されてません。
    利用するコードは簡単になるけど、ライブラリ導入の手間や難易度は高め。
    pypi に登録されているのは、同名の別ライブラリなので注意。

投稿2021/10/25 11:23

編集2021/10/25 23:47
teamikl

総合スコア8760

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

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

Tera0724

2021/11/09 03:49

細かなアドバイスありがとうございます。tree2つ同期させる方向で進めたところ、何とかスムーズなUIが作成できました!!! 返答遅くなり申し訳ありません!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.35%

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

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

質問する

関連した質問