【tkinter】place()を使ったWidgetの配置の方法

 

tkinterではwidget(例:Frame、Canvas)を配置するには3つの方法 grid, pack, placeがあります。

今回はplaceに焦点を当ててwidgetの配置方法についてまとめていきます。

 

 

前準備

place()の使い方について見る前にtemplate.pyapp.pyを用意します。この2つのプログラムを使ってplace()の使い方についてまとめていきます。

template.py

import tkinter as tk
from PIL import ImageTk


class Template(tk.Tk):
    def __init__(self, **kwargs):
        super(Template, self).__init__()
        self.title(kwargs.get("title", "tkinter"))
        self.geometry("+{}+{}".format(*kwargs.get("pos", (0, 0))))
        self.resizable(*kwargs.get("resize", (0, 0)))
        try:
            self.iconbitmap(kwargs.get("icon", None))
        except:
            if kwargs.get("icon", None) is not None:
                icon_name = kwargs.get("icon")
                icon_img = ImageTk.PhotoImage(file=icon_name)
                self.tk.call("wm", "iconphoto", self._w, icon_img)

    def run(self):
        self.mainloop()

template.pyはアプリケーションの雛形として用意しました。ここでは、アプリケーションのタイトル、起動時のアプリケーションの位置、アプリケーションの拡大拡小の設定、アプリケーションのアイコンについて設定をすることができます。設定はtemplate.pyを継承したクラスでするようにしてあります。

関連記事 - はじめてのtkinter ウィンドウを作って表示させる

 

app.py

import tkinter as tk
from template import Template


class App(Template):
    def __init__(self):
        super(App, self).__init__()
        self.createWidgets()
        self.attachWidgets()

    def createWidgets(self):
        pass

    def attachWidgets(self):
        pass


if __name__ == "__main__":
    app = App()
    app.run()

template.pyのTemplateクラスを継承しています。今回は特にアプリケーションのタイトル、位置、拡大拡小、アイコンの設定については行いません。createWidgets()Widgetの作成、attachWidgets()で作成したWidgetをウィンドウに配置していきます。

placeの使い方

今回はCanvasplace()を使って配置してみます。

そのためにまずはcreateWidgets()Canvasを用意します。

    def createWidgets(self):
        self.canvas = tk.Canvas(self, width=300, height=300, bg="white")

関連記事 - Canvasを使ってみる。

Widgetの配置位置(x, y)

createWidgets()Canvasを作成したので、今度はattachedWidgets()で作成したCanvasplace()を使ってウィンドウに貼り付けます。

    def attachWidgets(self):
        self.canvas.place(x=0, y=0)

app.pyを実行します。

$ python app.py

次のようなウィンドウが起動します。

f:id:pytry3g:20191222154557p:plain

place()で指定したxとyですが、デフォルトでは親Widgetの左上が0となり基準の位置となる点になります。ここでいう親Widgetとはメインウィンドウ(tk.Tk)のことで作成したCanvasはメインウィンドウの子Widgetにあたります。

位置の設定方法ですが、xの場合右側だと正、左側だと負の値を設定します。yの場合は下側が正、上側だと負の値を設定します。

試しに以下のようにxとyを変えてみます。

    def attachWidgets(self):
        self.canvas.place(x=10, y=20)

上のようにxとyの値を変えると下のようなウィンドウが起動します。

f:id:pytry3g:20191228095012p:plain

さきほど、デフォルトでは親Widgetの左上が0になると言いましたが、place()のオプションのひとつanchorの設定を変えることで、基準の位置となる点は変わってきます。

Widgetのサイズ(width, height)

Canvasを生成するときに幅と髙さを設定していましたが、place()のオプションでもwidth(幅)とheight(高さ)を指定することが可能です。

    def attachWidgets(self):
        self.canvas.place(x=10, y=20, width=10, height=30)

上のプログラムを実行すると、下のようにplace()で設定した幅と高さになりました。

f:id:pytry3g:20191228104249p:plain

相対的なサイズと位置

最後にサイズ(relwidth, relheight)と相対位置(relx, rely)について見ていきます。

    def createWidgets(self):
        self.canvas = tk.Canvas(self, width=300, height=300, bg="white")
        self.button = tk.Button(self.canvas, text="hello")

    def attachWidgets(self):
        self.canvas.place(x=0, y=0)
        self.button.place(x=5, y=5)

プログラムに少し変更を加えます。

createWidgets()attachedWidgets()を上のように変更してみました。

メインウィンドウにCanvasを貼り付け、そこにボタンを貼り付けています。

f:id:pytry3g:20191229001536p:plain

関連記事 - ボタンを作る

 

relwidthrelheightは親Widgetのwidth(幅)とheight(高さ)に対する相対的な長さを設定することができます。設定できる値の範囲は0.0~1.0です。

    def attachWidgets(self):
        self.canvas.place(x=0, y=0)
        self.button.place(x=5, y=5, relwidth=0.3, relheight=0.3)

上のようにrelwidthrelheightを設定して実行すると下のようなウィンドウが起動します。

f:id:pytry3g:20191229002301p:plain

例えば、relwidthの値を1.0にするとボタンの親WidgetであるCanvasの幅と同じ長さになるのでボタンが左端から右端までCanvas上に配置されるようになります。

 

relxrelyは親Widgetの位置(x, y)に対する相対的な位置を設定することができます。設定できる値の範囲は0.0~1.0です。

    def attachWidgets(self):
        self.canvas.place(x=0, y=0)
        self.button.place(relx=0.0, rely=0.3)

上のようにrelxrelyを設定して実行すると下のようなウィンドウが起動します。

f:id:pytry3g:20191229004907p:plain

おわり

placeの使い方について簡単に紹介しました。Widgetの配置方法には他にもgridpackがあるので、いずれ紹介したいと思います。

とりあえず今回はここまで。

参考記事 - Python - Tkinter place() Method - Tutorialspoint