【一つのframe】の上で 以下のようなデザインを達成したいのですが、そもそも
①PACKとGRIDを使い分けることができるのか、一度PACKを使いだしたら 同frame内では PACKの利用に統一しなければいけないのか?
②GRIDのrowとcolumnの考え方も、1あたりのメッシュを認識できていないのに どうやって位置を決定づけられるのだろう??
と疑問を抱いています。
1行目に左詰めで、2つのwidgetを並べて貼り付け、
2行目では一つのwidgetを横いっぱいに配置
3行目も 一つのwidgetを横いっぱいに配置
少し空白行をあけて....
再度別の一つのwidgetを横いっぱいにに配置
その直下に 2つのwidgetを左詰めで並べて配置
その直下で 2つのwidgetを右詰めで並べて配置
ということを達成したいのですが、どういう貼付け方を行うべきでしょうか?
ひょっとして1つのframeでは 無理でしょうか??
気になる質問をクリップする
クリップした質問は、後からいつでもMYページで確認できます。
またクリップした質問に回答があった際、通知やメールを受け取ることができます。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
回答2件
0
(1) PACKとGRIDを使い分けることができるのか、
一度PACKを使いだしたら 同frame内では PACKの利用に統一しなければいけないのか?
間に frame を挟むことで使い分けは可能です。
同frame内に PACKとGRID は混在できないので、統一する必要がありますが、
階層が異なる場合、例えばPACKで配置した子frame内でGRIDを使うことは可能です。
PLACE はこの制限を受けません。
(2) GRIDのrowとcolumnの考え方も、1あたりのメッシュを認識できていないのに
どうやって位置を決定づけられるのだろう??
座標指定が、ピクセル単位の(x,y)ではなくセル単位(row,column) となる。
各セルの width, height は、それぞれの行・列に配置されたウィジェットのうち
最大のモノが適応される…と考えると解りやすいのではないでしょうか。
1つのフレームという事で、実際にgrid を使って説明します。
(packの方が管理はしやすいのですが、「横に並べる」時にフレームを使います)
1行目に左詰めで、2つのwidgetを並べて貼り付け、
column を順に指定します。
2行目では一つのwidgetを横いっぱいに配置
3行目も 一つのwidgetを横いっぱいに配置
columnspan で横セルを結合します。
また rowconfigure と sticky=tk.NSWE でリサイズ時に最大化するように指定
少し空白行をあけて....
ttk.Separator 等がありますが、空のラベルを入れました。(ソース後述)
再度別の一つのwidgetを横いっぱいにに配置
2,3 行目と同じ。
その直下に 2つのwidgetを左詰めで並べて配置
1行目と同じ。
その直下で 2つのwidgetを右詰めで並べて配置
右詰めで column を指定します。
※ 説明の為に、row, column の表を作りましたが、
この様に管理するのはお勧めしません。
row, column 追加があった際の保守性が悪くなります。
回避策はソースコード内で説明しますが、
極力 rowやcolumn の指定にマジックナンバーを使わない事です。
python
1from types import SimpleNamespace 2import tkinter as tk 3from tkinter import ttk 4from tkinter.scrolledtext import ScrolledText 5 6 7def create_view(root): 8 parent = ttk.Frame(root, style="parent.TFrame") 9 10 labelA = ttk.Label(parent, text="Label", width=20, style="a.TLabel") 11 labelB = ttk.Label(parent, text="ListBox?", width=20, style="b.TLabel") 12 labelC = ttk.Label(parent, text="Label", width=20, style="c.TLabel") 13 14 buttonA = ttk.Button(parent, text="Button") 15 buttonB = ttk.Button(parent, text="Button") 16 buttonC = ttk.Button(parent, text="Button") 17 buttonD = ttk.Button(parent, text="Quit", command=root.destroy) 18 19 separator = ttk.Label(parent, style="a.TLabel") # As blank vertical space 20 21 text = ScrolledText(parent, height=10) 22 text.insert(tk.END, "ScrolledText") 23 message = tk.Message(parent, text="Message ....", width=200) 24 25 # NOTE: export all local variables 26 return SimpleNamespace(**locals()) 27 28 29def init_view_style(view): 30 # style config 31 bgcolor = "#dde7ee" 32 bgcolor2 = "#9bc2e6" 33 fgcolor = "yellow" 34 font = ("", 10, "bold") 35 36 # Style non-ttk widgets 37 view.root.configure(bg=bgcolor) 38 view.text.config(insertbackground="white", bg="black", fg=fgcolor, borderwidth=0, font=font) 39 view.message.configure(fg=fgcolor, bg=bgcolor2, font=font) 40 41 # ttk widgets style 42 style = ttk.Style(view.root) 43 style.configure("TLabel", font=("", 10, "bold"), anchor="c") 44 style.configure("a.TLabel", background=bgcolor) 45 style.configure("b.TLabel", background="black", foreground=fgcolor) 46 style.configure("c.TLabel", background=bgcolor2, foreground=fgcolor) 47 style.configure("TButton", background=bgcolor) 48 style.configure("parent.TFrame", background=bgcolor) 49 50 51def init_view_layout(view): 52 # Grid Layout を使う時の Tips 53 54 # 行毎にレイアウトを呼ぶ出す部分を関数化し 55 # デコレーターによりリスト `rows` に入れます。 56 # 後でまとめて、順番に行番号 `row` を与えて呼び出します。 57 58 # これにより、行の入れ替えや追加が容易に管理できるようになります。 59 60 from itertools import count 61 from functools import partial 62 63 rows = [] 64 addrow = rows.append 65 maxcolumn = 6 66 right = lambda column: maxcolumn-column-1 67 nopad = {"padx":0, "pady": 0} 68 69 def _finish_layout(): 70 for row, func in enumerate(rows): 71 func(row, partial(next, count()), **nopad) 72 73 parent = view.parent 74 parent.pack(fill=tk.BOTH, expand=True, padx=10, pady=10) 75 parent.grid_columnconfigure(2, weight=True) 76 77 @addrow 78 def row_header(row, col, **kw): 79 view.labelA.grid(row=row, column=col(), **kw) 80 view.labelB.grid(row=row, column=col(), **kw) 81 82 @addrow 83 def row_scrolledtext(row, col, **kw): 84 view.text.grid(row=row, column=col(), columnspan=maxcolumn, sticky=tk.NSEW, **kw) 85 parent.grid_rowconfigure(row, weight=True) 86 87 @addrow 88 def row_center_button(row, col, **kw): 89 view.buttonA.grid(row=row, column=col(), columnspan=maxcolumn) 90 91 @addrow 92 def row_blank_separator(row, col, **kw): 93 view.separator.grid(row=row, column=col(), sticky=tk.NSEW, **kw) 94 95 @addrow 96 def row_message(row, col, **kw): 97 view.message.grid(row=row, column=col(), columnspan=maxcolumn, sticky=tk.NSEW, **kw) 98 parent.grid_rowconfigure(row, weight=True) 99 100 @addrow 101 def row_bottom_label(row, col, **kw): 102 view.buttonB.grid(row=row, column=col(), sticky=tk.NSEW, **kw) 103 view.labelC.grid(row=row, column=col(), sticky=tk.NSEW, **kw) 104 105 @addrow 106 def row_footer(row, col, **kw): 107 view.buttonD.grid(row=row, column=right(col()), sticky=tk.NSEW, **kw) 108 view.buttonC.grid(row=row, column=right(col()), sticky=tk.NSEW, **kw) 109 110 _finish_layout() 111 112 113def main(): 114 root = tk.Tk() 115 root.title("grid layout demo") 116 view = create_view(root) 117 init_view_style(view) 118 init_view_layout(view) 119 root.mainloop() 120 121 122if __name__ == '__main__': 123 main() 124
init_view_style(view)
の行をコメントアウトすると、スタイル適応なしで実行されます。
追記: packでの実装例
最小限のコードになりますが、簡単な方法では、
「横に並べる」部分だけを別フレームに切り出し、
side="left"
を指定して横並びにします。
python
1import tkinter as tk 2from tkinter import ttk 3from tkinter.scrolledtext import ScrolledText 4 5 6def main(): 7 root = tk.Tk() 8 9 frameA = ttk.Frame(root) 10 frameA.pack(fill=tk.BOTH) 11 ttk.Label(frameA, text="Label", width=10).pack(side=tk.LEFT) 12 ttk.Label(frameA, text="ListBox?", width=10).pack(side=tk.LEFT) 13 14 text = ScrolledText(root, height=10) 15 text.pack(fill=tk.BOTH, expand=1) 16 text.insert(tk.END, "ScrolledText") 17 18 ttk.Button(root, text="Button").pack() 19 ttk.Label(root).pack() 20 tk.Message(root, text="Message", width=200, bg="black", fg="white").pack(fill=tk.BOTH, expand=1) 21 22 frameB = ttk.Frame(root) 23 frameB.pack(fill=tk.BOTH) 24 ttk.Button(frameB, text="Button", width=10).pack(side=tk.LEFT) 25 ttk.Label(frameB, text="Label", width=10).pack(side=tk.LEFT) 26 27 ttk.Button(root, text="Quit", command=root.destroy).pack(side=tk.RIGHT) 28 ttk.Button(root, text="Button").pack(side=tk.RIGHT) 29 30 root.mainloop() 31 32 33if __name__ == '__main__': 34 main() 35
投稿2020/05/07 08:06
編集2020/05/07 10:21総合スコア8760
0
ベストアンサー
①
YES:LayoutManagerは同じマスターウィンドウ上でミックスするべきではありません。
②
下記のようにExcel上でレイアウトを構築するイメージです。
・それぞれの行・列の幅をどうするか
・スペースをどうするか
は後から構いませんので、とりあえずはどの行・列にWidgetを配置するかだけを考えると良いかと思います。
上記のレイアウトが決まれば、
1.Widgetの width
パラメータを設定することで、それぞれ列の幅を設定する
2.スペースが必用な箇所のgrid()
のパラメータに padx
,pady
を渡す
3.Windowサイズに変更が生じた際に変更される行・列をgrid_rowconfigure()
,grid_columnconfigure()
のweight
パラメータで設定する
4.Windowサイズに変更が生じ、行・列の幅が変更された際に Widgetの挙動を grid()
のsticky
パラメータで設定する
あたりでそれっぽい挙動になるのではないでしょうか
Python
1import tkinter as tk 2 3root = tk.Tk() 4label1 = tk.Label(root, text='Label', width=10) 5label1.grid(row=0, column=0) 6listbox = tk.Listbox(root, height=1, width=10) 7listbox.grid(row=0, column=1) 8text1 = tk.Text(root) 9text1.grid(row=1, column=0, columnspan=5, sticky=tk.W+tk.E) 10button1 = tk.Button(root, text='Button', width=10) 11button1.grid(row=2, column=2, padx=20, pady=(0, 20)) 12text2 = tk.Text(root) 13text2.grid(row=3, column=0, columnspan=5, sticky=tk.W+tk.E) 14button2 = tk.Button(root, text='Button', width=10) 15button2.grid(row=4, column=0) 16label2 = tk.Label(root, text='Label', width=10) 17label2.grid(row=4, column=1) 18button3 = tk.Button(root, text='Button', width=10) 19button3.grid(row=5, column=3) 20button4 = tk.Button(root, text='Button', width=10) 21button4.grid(row=5, column=4) 22 23root.grid_rowconfigure(1, weight=1) 24root.grid_rowconfigure(3, weight=1) 25root.grid_columnconfigure(2, weight=1) 26 27root.mainloop()
投稿2020/05/07 08:06
編集2020/05/08 01:25総合スコア15898
あなたの回答
tips
太字
斜体
打ち消し線
見出し
引用テキストの挿入
コードの挿入
リンクの挿入
リストの挿入
番号リストの挿入
表の挿入
水平線の挿入
プレビュー
質問の解決につながる回答をしましょう。 サンプルコードなど、より具体的な説明があると質問者の理解の助けになります。 また、読む側のことを考えた、分かりやすい文章を心がけましょう。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2020/05/07 08:29
2020/05/07 09:46 編集
2020/05/07 08:52