PythonのtkinterでTreeviewウィジェットを使う際、関数を経由してヘッダーや行を追加すると、表示幅が不自然に広がる現象があります。本記事では、この原因と具体的な解決策をわかりやすく解説します。
Treeviewの列幅が変わる仕組み
Treeviewは内部で各列の最小幅と内容に応じた要求幅を計算して表示します。通常はpack()やgrid()でウィジェットを配置する際にwidth属性を指定すれば、列幅は想定通りになります。
しかし、関数経由で列を追加した場合、ウィジェットがまだ表示されていない段階で列幅を計算することになり、reqwidthが過大になってしまうことがあります。
関数経由で幅が広がる原因
主な原因は以下の通りです。
- 関数内でTreeviewの構築を行うタイミングが早すぎて、ウィジェットがまだ描画されていない
- 列幅自動計算時にスケーリングが影響している
- pack()やgrid()前に列幅を設定している
結果として、reqwidthが過大になり、見かけ上列が倍くらいの幅で表示されることがあります。
実例と修正方法
関数内で列幅が広がる場合、update_idletasks()を使用してウィジェットの描画を先に行う方法が有効です。
例えば。
def setup_tree(tree):
tree['columns'] = ('col1','col2')
for col in tree['columns']:
tree.heading(col, text=col)
tree.column(col, width=100)
tree.update_idletasks() # 描画を先に行う
この処理により、関数経由でも列幅が正しく計算され、横幅が不自然に広がることを防げます。
pack()やgrid()のタイミング調整
もうひとつの方法として、Treeviewを先にpack()またはgrid()で配置し、その後に関数でヘッダーや行を追加する方法があります。
例。
tree = ttk.Treeview(root, show='headings')
tree.pack()
add_rows_and_columns(tree)
これにより、ウィジェットの描画済みサイズが計算され、列幅が適切になります。
まとめ
Treeviewで関数経由の列追加で横幅が広がる場合、主に描画タイミングと自動幅計算が原因です。update_idletasks()の使用や、先にpack()してから列追加する方法で解決できます。これらの手順を踏むことで、関数化しても列幅が正しく表示されるようになります。

コメント