asana_yui
@asana_yui (結 麻菜)

Are you sure you want to delete the question?

Leaving a resolved question undeleted may help others!

Tkinterのウィジェット配置に関する質問です

質問内容

 皆様にお力をお借りしたいと考えまして、質問をさせていただきます。表題の通りなのですが、ウィンドウ上のラベルとボタンが求める形にならず困っています。ぜひ我こそはという人はよろしくお願いします。

環境

OS: Windows10
Python: 3.8.2

したいこと

 理想としては以下の画像のようにすることです。(画像はそれっぽく作ったパワポのやつ)
hope.png
条件としては、
1. ウィンドウのサイズは800x440です(geometryメソッドから指定します。)
2. Label_Aには全角文字で横45文字、縦8文字ほどが入ります。
3. ウィンドウの伸縮はさせるつもりがないので、考慮する必要はありません。(窓の伸縮が固定してもしなくてもok)

現状

 現状はこれです。tk.png

class Frame(Tk.Frame):
    def __init__(self, master=None):
        Tk.Frame.__init__(self, master)
        self.master.title("TEST")
        self.master.geometry("800x440")

        self.label_A = Tk.Label(
            self,
            text="Label_A"
        )
        self.label_A.pack(padx=5, pady=5, fill="both", expand=True)

        self.label_B = Tk.Label(
            self,
            text = "Label_B"
        )
        self.label_B.pack(padx=5, fill="both", expand=True, side="left")

        self.button_A = Tk.Button(
            self,
            text = "Button_A"
        )
        self.button_A.pack(padx=5, fill="both", expand=True, side="left")

        self.button_B = Tk.Button(
            self,
            text = "Button_B"
        )
        self.button_B.pack(padx=5, fill="both", expand=True, side="left")

if __name__ == "__main__":
    f = Frame()
    f.pack()
    f.mainloop()

 ソースコードでは、クラスを定義してという風にやっていますがそこは制限ではありません。理想の姿になればので、皆様のやりやすい記述の仕方で結構です。よろしくお願いします。

0

1Answer

まず全体が上に寄っているのは Frame の expand と fill をセットしていないからなので、以下のようにします。

if __name__ == "__main__":
    f = Frame()
    f.pack(fill="both", expand=True)
    f.mainloop()

こうすると label A だけが上下に広がって残りの要素が下端に押しやられます。そこで Frame の中に Frame を置いてみました。

import tkinter as Tk

class Frame(Tk.Frame):
    def __init__(self, master=None):
        Tk.Frame.__init__(self, master)
        self.master.title("TEST")
        self.master.geometry("800x440")

        self.frame_top = FrameTop(self)
        self.frame_top.pack(fill="both", expand=True)
        self.frame_bottom = FrameBottom(self)
        self.frame_bottom.pack(fill="both", expand=True)

class FrameTop(Tk.Frame):
    def __init__(self, master=None):
        Tk.Frame.__init__(self, master)

        self.label_A = Tk.Label(
            self,
            text="Label_A"
        )
        self.label_A.pack(padx=5, pady=5, fill="both", expand=True)

class FrameBottom(Tk.Frame):
    def __init__(self, master=None):
        Tk.Frame.__init__(self, master)

        self.label_B = Tk.Label(
            self,
            text = "Label_B"
        )
        self.label_B.pack(padx=5, fill="both", expand=True, side="left")

        self.button_A = Tk.Button(
            self,
            text = "Button_A"
        )
        self.button_A.pack(padx=5, fill="both", expand=True, side="left")

        self.button_B = Tk.Button(
            self,
            text = "Button_B"
        )
        self.button_B.pack(padx=5, fill="both", expand=True, side="left")

if __name__ == "__main__":
    f = Frame()
    f.pack(fill="both", expand=True)
    f.mainloop()

これで上段と下段の高さが均等な配置になりました。

1Like

Comments

  1. @asana_yui

    Questioner

    まさにやりたかったことそのものです!素早い回答ありがとうございます!
    数時間調べていてもよくわからなかったことなのですが、聞いてよかったです!
  2. よかったです。これだとラベルの文字が中央に寄ってしまうので、パワポ通り上寄せにするならさらに Frame を入れ子にするとよさそうです。

    それから、ボタンの領域を広げてもボタンの枠線は縦方向に広がらないようです。領域全体にクリック判定はあるようなので描画の問題だと思いますが。 Tk は使ったことがないのでこれ以上は分かりませんでした。

Your answer might help someone💌