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

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

ただいまの
回答率

89.10%

Python3 Tkinter ウィジェット間に罫線を表示してかつウィジェットの開始端を揃えたい

解決済

回答 1

投稿 編集

  • 評価
  • クリップ 1
  • VIEW 79

person

score 70

Tkinterでウィジェット間に罫線を表示したいので、次のようにフレームを配置しました。

import tkinter as tk

win = tk.Tk()

win.rowconfigure(0, weight=1)
win.columnconfigure(0, weight=1)

f0 = tk.Frame(win)
f0.grid(sticky="nsew")

f0.rowconfigure((0,1,2), weight=1)
f0.columnconfigure(0, weight=1)

f1 = tk.Frame(f0, relief="solid", bd=1)
f1.grid(row=0, column=0, sticky="nsew")
f2 = tk.Frame(f0, relief="solid", bd=1)
f2.grid(row=1, column=0, sticky="nsew")
f3 = tk.Frame(f0, relief="solid", bd=1)
f3.grid(row=2, column=0, sticky="nsew")

f1.rowconfigure(0, weight=1)
f1.columnconfigure(1, weight=1)
f2.rowconfigure(0, weight=1)
f2.columnconfigure(1, weight=1)
f3.rowconfigure(0, weight=1)
f3.columnconfigure(1, weight=1)

l1 = tk.Label(f1, text="a"*10)
l1.grid(row=0, column=0, sticky="nsew")
l2 = tk.Label(f2, text="a"*20)
l2.grid(row=0, column=0, sticky="nsew")
l3 = tk.Label(f3, text="a"*30)
l3.grid(row=0, column=0, sticky="nsew")

e1 = tk.Entry(f1)
e1.grid(row=0, column=1, sticky="nsew")
e2 = tk.Entry(f2)
e2.grid(row=0, column=1, sticky="nsew")
e3 = tk.Entry(f3)
e3.grid(row=0, column=1, sticky="nsew")

win.mainloop()

実行結果

実行結果

ここでエントリ(テキストボックス)の開始端を3つとも揃えたいのですが、
行ごと(可能であれば格子状)に罫線を表示しながら揃えることができません。

理想としては、下のコードのようにラベルテキストが最も長いものの末尾に揃えたいです。

可能でしょうか?

外枠の罫線表示でウィジェットを揃えて配置。

import tkinter as tk

win = tk.Tk()

win.rowconfigure(0, weight=1)
win.columnconfigure(0, weight=1)

f0 = tk.Frame(win) # フレームの内側にreliefは設定できない・・・?
f0.grid(sticky="nsew")

f0.rowconfigure((0,1,2), weight=1)
f0.columnconfigure(1, weight=1)

l1 = tk.Label(f0, text="a"*10)
l1.grid(row=0, column=0, sticky="nsw")
l2 = tk.Label(f0, text="a"*20)
l2.grid(row=1, column=0, sticky="nsw")
l3 = tk.Label(f0, text="a"*30)
l3.grid(row=2, column=0, sticky="nsw")

e1 = tk.Entry(f0)
e1.grid(row=0, column=1, sticky="nsew")
e2 = tk.Entry(f0)
e2.grid(row=1, column=1, sticky="nsew")
e3 = tk.Entry(f0)
e3.grid(row=2, column=1, sticky="nsew")

win.mainloop()

実行結果
実行結果2

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

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

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

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 1

checkベストアンサー

0

簡単な方法は、各列を width で固定幅にして全て個別の 枠付きFrame に入れる方法です。

Label 自体にも borderwidth や relief 指定が可能ですが、
横幅を揃える為に `sticky' 指定すると中央に来てしまう為、
ラベルの文字を左寄せにする為には、Frame を挟むなどの追加で対策が必要になってしまいます。

relief を用いる罫線表示の場合、もう一つ問題があって
各セルがボーダーを持つため、ボーダーの太さが二重になるというものです。
これの対策としては、背景色をボーダー色として、padx, pady で片側のみ余白を作る方法があります。
(サイズ1の罫線を表示させたい場合)

追記

イメージ説明

import tkinter as tk

border_color = "black"
grid_options = dict(padx=(1,0), pady=(1,0), sticky="nwse")

root = tk.Tk()
frame = tk.Frame(root, bg=border_color)
frame.pack(fill=tk.BOTH, expand=True)
frame.grid_columnconfigure(1, weight=True)

bgcolor = root.cget("bg")

for row, num in enumerate([3, 6, 9]):
    field = tk.Frame(frame, bg=bgcolor, relief=tk.SOLID)
    label = tk.Label(field, text="a" * num)
    label.pack(fill=tk.X, side=tk.LEFT)
    field.grid(row=row, column=0, **grid_options)
    entry = tk.Entry(frame)
    entry.grid(row=row, column=1, **grid_options)
    frame.grid_rowconfigure(row, weight=True)

root.mainloop()

他の方法

  • 自分でレイアウトコンテナのクラスを実装する。→ 問題点: 実装方法のサンプルがほとんどない
  • 既存のライブラリを探して使う。 pypi.org で 「table」 や「grid」を検索
    軽く探してみましたが、特にこれというものは有りませんでした。
    エクセルの様なスプレッドシード的な実装はありますが、
    目的が見栄えだけの場合は少し冗長になります。

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

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

  • ただいまの回答率 89.10%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる