【Python/tkinter】Canvas(キャンバス)の作成

Canvasは、線や円などの図形や画像を表示するためのベースとなるものとなります。

C#でいうところのPictureBoxです。

Canvasには、図形や画像を表示する以外にも描画領域をスクロールできる機能もありますが、今回はCanvasの作成についてです。

ただ、Canvasを配置しただけの簡単なサンプルは以下のようになります。

 

(実行画面)

(プログラム)

import tkinter as tk

class Application(tk.Frame):
    def __init__(self, master = None):
        super().__init__(master)

        self.master.title("タイトル")    # ウィンドウタイトル
        self.master.geometry("300x200") # ウィンドウサイズ(幅x高さ)

        # Canvasの作成
        canvas = tk.Canvas(
            self.master, 
            width = 200,
            height = 100,
            bg = "cyan"
            )
        # Canvasを配置
        canvas.pack()

if __name__ == "__main__":
    root = tk.Tk()
    app = Application(master = root)
    app.mainloop()

オプション

オプション名 説明
background 背景色を指定します。(bgと同じ)
bd 枠線の太さを指定します。(borderwidthと同じ)
bg 背景色を指定します。(backgroundと同じ)
borderwidth 枠線の太さを指定します。(bdと同じ)
closeenough
confine
cursor ウィジェット上にマウスポインタがある際のカーソルの種類を指定します。
(参考)https://tkdocs.com/shipman/cursors.html
height キャンバスの高さを指定します。
highlightbackground
highlightcolor
highlightthickness
insertbackground
insertborderwidth
insertofftime
insertontime
insertwidth
offset
relief キャンバスの枠線のスタイルを指定します。
【設定値】tk.RAISED, tk.GROOVE, tk.SUNKEN, tk.RIDGE, tk.FLAT
scrollregion スクロールする領域のサイズを指定します。
selectbackground
selectborderwidth
selectforeground
state ウィジェットの有効(NORMAL)/無効(DISABLED,操作できない状態)を指定します。
【設定値】tk.NORMAL, tk.DISABLED
【初期値】tk.NORMAL
takefocus
width キャンバスの幅を指定します。
xscrollcommand 横方向にスクロールするスクロールバーの スクロールバー.set を指定します。
xscrollincrement 横方向のスクロールバーの矢印をクリックしたときの移動量を指定します。
yscrollcommand 縦方向にスクロールするスクロールバーの スクロールバー.set を指定します。
yscrollincrement 縦方向のスクロールバーの矢印をクリックしたときの移動量を指定します。

 

関連記事

Canvasに画像を表示する方法については、以下のページを参照ください。

【Python/tkinter】Canvasに画像を表示する

【Python/tkinter】名前を付けて保存ダイアログボックスの表示

名前を付けて保存ダイアログボックスを表示するには、tkinter.filedialogモジュールのasksaveasfilename()関数を使います。

以下にシンプルなサンプルプログラムを示します。

from tkinter import filedialog

filename = filedialog.asksaveasfilename()
print(filename)

(実行結果)

 

オプション

オプション名 説明
parent ダイアログを表示する親のウィンドウを指定します。
title ダイアログのタイトルを指定します。
initialdir 最初に表示されるディレクトリを指定します。
initialfile 最初に選択されているファイル名を指定します。
filetypes 選択可能なファイルの種類を設定します。
defaultextension 拡張子が入力されない場合に追加する拡張子を指定します。

(参考)

https://docs.python.org/ja/3/library/dialog.html?highlight=askopenfilename#module-tkinter.filedialog

 

名前を付けて保存ダイアログボックスはファイルを開くダイアログボックスとも似ていますが、defaultextensionオプションが異なります。

これは名前を付けて保存ダイアログの「ファイル名」の部分に拡張子を指定しなかった場合に、defaultextensionオプションで指定した拡張子が付加されます。

 

それでは、defaultextensionオプションを指定せずにfiletypesオプションを指定すると、どうなるか?というと、「ファイル名」の部分に、拡張子を付けずにファイル名を入力しても、「ファイルの種類」で指定された拡張子で、拡張子が自動で付加される事はありません。

filename = filedialog.asksaveasfilename(
    filetypes = [("Bitmap", ".bmp"), ("PNG", ".png"), ("JPEG", ".jpg"), ("Tiff", ".tif") ], # ファイルフィルタ
    )

そのため、filetypesオプションとdefaultextensionオプションは両方指定して、以下のようにします。

from tkinter import filedialog

filename = filedialog.asksaveasfilename(
    title = "名前を付けて保存",
    filetypes = [("Bitmap", ".bmp"), ("PNG", ".png"), ("JPEG", ".jpg"), ("Tiff", ".tif") ], # ファイルフィルタ
    initialdir = "./", # 自分自身のディレクトリ
    defaultextension = "bmp"
    )
print(filename)

このようにすると、「ファイルの種類」で指定された拡張子で、自動で拡張子が付加されます。

上記のプログラムではdefaultextension が “bmp”ですが、「ファイルの種類」がPNGのときは、ちゃんと.pngを付加してくれます。

もっというと、defaultextension = “” としても、「ファイルの種類」で指定された拡張子が付加されます。

(実行結果)

 

関連記事

【Python/tkinter】ファイルを開くダイアログボックスの表示

【Python/tkinter】Frame(フレーム)

Frameはいくつかのウィジェットを配置するための枠、まさにフレームです。
C#でいうところのPanelと同じです。

Frameを使うとウィジェットの配置の自由度が増します。
ウィジェットを配置するには、pack,grid,placeの3つのメソッドがありますが、一つのコンテナ(Frameなど)にはpack,grid,placeの3つの混在使用ができないのですが、複数のFrameを用いて、まずは大枠を作り、そこにウィジェットを配置すると、比較的簡単にイメージ通りの画面が作成できると思います。

Frameを使って、ツールバー、ステータスバー、右カラムを作ってみたいと思います。

(実行画面)

(プログラム)

import tkinter as tk

class Application(tk.Frame):
    def __init__(self, master = None):
        super().__init__(master)

        self.master.geometry("300x200") 

        #---------------------------------------
        #  ツールバー
        #---------------------------------------
        # ツールバー用Frame
        frame_toolbar = tk.Frame(self.master)
        # ツールボタン
        button1 = tk.Button(frame_toolbar, text = "1", width = 2)
        button2 = tk.Button(frame_toolbar, text = "2", width = 2)
        button3 = tk.Button(frame_toolbar, text = "3", width = 2)
        # ボタンをフレームに配置
        button1.pack(side = tk.LEFT)
        button2.pack(side = tk.LEFT)
        button3.pack(side = tk.LEFT)
        # ツールバーをウィンドの上に配置
        frame_toolbar.pack(fill = tk.X)

        #---------------------------------------
        #  ステータスバー
        #---------------------------------------
        # ツールバー用Frame
        frame_statusbar = tk.Frame(self.master, relief = tk.SUNKEN, bd = 2)
        # ステータスラベル
        label = tk.Label(frame_statusbar, text = "StatusLabel")
        # ラベルをフレームに配置
        label.pack(side = tk.LEFT)
        # ステータスバーをウィンドの下に配置
        frame_statusbar.pack(side = tk.BOTTOM, fill = tk.X)

        #---------------------------------------
        #  右カラム
        #---------------------------------------
        # 右カラム用Frame
        frame_column = tk.Frame(self.master, relief = tk.SUNKEN, bd = 2, width = 100)
        frame_column.propagate(False) # フーレムサイズの自動調整を無効にする
        # チェックボタン
        check1 = tk.Checkbutton(frame_column, text = "Check1")
        check2 = tk.Checkbutton(frame_column, text = "Check2")
        check3 = tk.Checkbutton(frame_column, text = "Check3")
        # チェックボタンをフレームに配置
        check1.pack()
        check2.pack()
        check3.pack()
        # 右カラムをウィンドの右に配置
        frame_column.pack(side = tk.RIGHT, fill = tk.Y)

        #---------------------------------------
        #  残りの領域
        #---------------------------------------
        frame = tk.Frame(self.master, relief = tk.SUNKEN, bd = 2, bg = 'dark cyan')
        frame.pack(expand = True, fill = tk.BOTH)

if __name__ == "__main__":
    root = tk.Tk()
    app = Application(master = root)
    app.mainloop()

ポイント

  • 枠線の種類(relief)を指定するときは、枠線の太さ(bd)も指定する事。(枠線の太さは初期値が0のため)
  • Frameの幅(width)もしくは高さ(height)を数値で指定したいときは、
    フレーム.propagate(False)メソッドを呼ぶこと。
    propagate()を呼ばない場合、フレーム内のウィジェットに合わせてサイズが自動調整されます。
  • Frameを残りの領域全体に広げたい場合はpack時にexpand = True, fill = tk.BOTHの両方を指定すること

オプション

オプション名 説明
bd 枠線の太さを指定します。(borderwidthと同じ)
borderwidth bdと同じ
bg 背景色を指定します。(backgroundと同じ)
background bgと同じ
cursor ウィジェット上にマウスポインタがある際のカーソルの種類を指定します。
(参考)https://tkdocs.com/shipman/cursors.html
height フレームの高さを画素数で指定します。
highlightbackground
highlightcolor
highlightthickness
padx フレームの内側に配置するウィジェットまでの横方向の隙間を指定します。
【初期値】0
pady フレームの内側に配置するウィジェットまでの縦方向の隙間を指定します。
【初期値】0
relief ボタンのスタイルを指定します。
【設定値】tk.RAISED, tk.GROOVE, tk.SUNKEN, tk.RIDGE, tk.FLAT
takefocus
width フレームの幅を画素数で指定します。
wraplength 文字の折り返し幅を指定します。

 

【Python/tkinter】Menu(メニュー)

ウィンドウにメニューを追加するには、Menuクラスを用います。

メニューで良く使いそうな機能のサンプルプログラムを作成しました。

(実行画面)

ファイル関連のメニュー

表示メニュー(チェックボタンで作成しています)

選択メニュー(ラジオボタンで作成しています)

(サンプルプログラム)

import tkinter as tk
from tkinter import filedialog

class Application(tk.Frame):
    def __init__(self, master = None):
        super().__init__(master)
        self.pack()

        self.master.title("メニューの作成")       # ウィンドウタイトル
        self.master.geometry("300x150")     # ウィンドウサイズ(幅x高さ)
        
        # ------------------------------------------------
        # メニューの作成

        # メニューバーの作成
        menubar = tk.Menu(self)

        # ファイル
        menu_file = tk.Menu(menubar, tearoff = False)
        menu_file.add_command(label = "ファイルを開く",  command = self.menu_file_open_click,  accelerator="Ctrl+O")
        menu_file.add_command(label = "名前を付けて保存", command = self.menu_file_saveas_click, accelerator="Ctrl+S")
        menu_file.add_separator() # 仕切り線
        menu_file.add_command(label = "終了",            command = self.master.destroy)
        # ショートカットキーの関連付け
        menu_file.bind_all("<Control-o>", self.menu_file_open_click)
        menu_file.bind_all("<Control-s>", self.menu_file_saveas_click)

        # 表示(Checkbutton)
        menu_disp = tk.Menu(menubar, tearoff = False)
        self.disp1_value = tk.BooleanVar()
        self.disp2_value = tk.BooleanVar()
        self.disp3_value = tk.BooleanVar()
        menu_disp.add_checkbutton(label = "表示1", command = self.menu_disp1_click, variable = self.disp1_value)
        menu_disp.add_checkbutton(label = "表示2", command = self.menu_disp2_click, variable = self.disp2_value)
        menu_disp.add_checkbutton(label = "表示3", command = self.menu_disp3_click, variable = self.disp3_value)

        # 選択(Radiobutton)
        self.radio_val = tk.IntVar() # ラジオボタンの値
        menu_select = tk.Menu(menubar, tearoff = False)
        menu_select.add_radiobutton(label = "選択1", command = self.menu_select_click, variable = self.radio_val, value = 1)
        menu_select.add_radiobutton(label = "選択2", command = self.menu_select_click, variable = self.radio_val, value = 2)
        menu_select.add_radiobutton(label = "選択3", command = self.menu_select_click, variable = self.radio_val, value = 3)

        # メニューバーに各メニューを追加
        menubar.add_cascade(label="ファイル", menu = menu_file)
        menubar.add_cascade(label="表示",     menu = menu_disp)
        menubar.add_cascade(label="選択",     menu = menu_select)

        # 親ウィンドウのメニューに、作成したメニューバーを設定
        self.master.config(menu = menubar)

    def menu_file_open_click(self, event=None):
        print("「ファイルを開く」が選択された")
        filename = filedialog.askopenfilename(
            title = "ファイルを開く",
            initialdir = "./" # 自分自身のディレクトリ
            )
        print(filename)

    def menu_file_saveas_click(self, event=None):
        print("「名前を付けて保存」が選択された")

    def menu_disp1_click(self):
        print("「表示1」が選択された")
        print(f"チェック状態は{self.disp1_value.get()}")

    def menu_disp2_click(self):
        print("「表示2」が選択された")
        print(f"チェック状態は{self.disp2_value.get()}")

    def menu_disp3_click(self):
        print("「表示3」が選択された")
        print(f"チェック状態は{self.disp3_value.get()}")

    def menu_select_click(self):
        print(self.radio_val.get(), "番目のラジオボタンが選択されました。")

if __name__ == "__main__":
    root = tk.Tk()
    app = Application(master = root)
    app.mainloop()

ポイント

  • プルダウンで表示されるメニューが1つのMenuクラスオブジェクトとなり、各メニューの項目はadd_command()メソッドで追加します。
  • Menuクラスオブジェクトを親のMenuに追加するときは、add_cascade()メソッドを用います。

Menuクラスオプション

オプション名 説明
activebackground マウスポインタが各メニューの上にあるときの背景色を指定します。
activeborderwidth
選択されたメニューの枠の太さを指定します???
実質的にメニューの行間が広がります。
activeforeground マウスポインタが各メニューの上にあるときの文字色を指定します。
background 通常時の背景色を指定します。(bgと同じ)
bd 枠線の太さを指定します。(指定できない?)
bg backgroundと同じ
bitmap モノクロのBitmapを指定します。
(参考)https://anzeljg.github.io/rin2/book2/2405/docs/tkinter/bitmaps.html
borderwidth bdと同じ
cursor ウィジェット上にマウスポインタがある際のカーソルの種類を指定します。(指定できない?
disabledforeground add_command()メソッドで追加したメニューのstateオプションで無効(DISABLED)に設定している際の文字色を設定します。
fg add_command()メソッドで追加したメニューの文字色を設定します。
foreground fgと同じ
relief ボタンのスタイルを指定します。(指定できない?
【設定値】tk.RAISED, tk.GROOVE, tk.SUNKEN, tk.RIDGE, tk.FLAT
【初期値】tk.FLAT(枠線なし)
selectcolor チェックボックス(チェックのある四角)の背景色を指定します。(指定できない?
takefocus
tearoff 必ずFalse(0)を指定します。
指定しない場合、破線が表示されます。
tearoffcommand
title
type

メソッド

メソッド 説明
add_command() メニュー項目を追加します。
add_radiobutton() ラジオボタンを追加します。(ただし、見た目はチェックボタンと同じ)
add_checkbutton() チェックボタンを追加します。
add_cascade() 親のMenuにMenuクラスオブジェクトを追加します。
add_separator() 仕切り線を追加します。
add( type, options )
delete( startindex [, endindex ]) メニューの項目をstartindex ~(endindex )まで削除します。
entryconfig( index, options ) メニューのindex番号を指定して、オプション設定値を設定、変更します。
index(item) メニューの文字列を指定してindex番号を取得します。
insert_separator ( index ) 指定した番号の位置に仕切り線を挿入します。
invoke ( index ) チェックボックスの場合、チェックの選択/非選択状態が切り替わります。
ラジオボタンの場合、選択されている項目が切り替わります。
type ( index ) 指定した番号のタイプを取得します。
cascade,  checkbutton,  command,  radiobutton,  separator, tearoff のいづれか

(補足)

メニューのindex番号ですが、私の環境では、上のメニューの番号は1から始まり、

ドロップダウンで表示されるメニューは0始まりとなっていました。

念のためindex()メソッドで、メニューの文字列指定でindex番号を取得した方が安全かも?しれません。

【Python/tkinter】Radiobutton(ラジオボタン)

ラジオボタンはRadiobuttonクラスによって作成します。

チェックボタンでは他のチェックボタンとは関係なくチェック/チェック無しの状態が選べましたが、ラジオボタンは複数のラジオボタンの中から1つだけ選択する場合に用いられます。

 

以下に簡単なサンプルを示します。

import tkinter as tk

class Application(tk.Frame):
    def __init__(self, master = None):
        super().__init__(master)

        self.master.title("ラジオボタンの作成")     # ウィンドウタイトル
        self.master.geometry("300x150")             # ウィンドウサイズ(幅x高さ)

        # ラジオボタンの値
        self.radio_value = tk.IntVar(value = 1)     # 初期値を設定する場合
        #self.radio_value = tk.IntVar()             # 初期値を設定しないと0になる
        
        # ラジオボタンの作成
        radio0 = tk.Radiobutton(self.master, 
                           text = "ラジオボタン0",      # ラジオボタンの表示名
                           command = self.radio_click,  # クリックされたときに呼ばれるメソッド
                           variable = self.radio_value, # 選択の状態を設定する
                           value = 0                    # ラジオボタンに割り付ける値の設定
                           )

        radio1 = tk.Radiobutton(self.master, 
                           text = "ラジオボタン1",      # ラジオボタンの表示名
                           command = self.radio_click,  # クリックされたときに呼ばれるメソッド
                           variable = self.radio_value, # 選択の状態を設定する
                           value = 1                    # ラジオボタンに割り付ける値の設定
                           )

        radio2 = tk.Radiobutton(self.master, 
                           text = "ラジオボタン2",      # ラジオボタンの表示名
                           command = self.radio_click,  # クリックされたときに呼ばれるメソッド
                           variable = self.radio_value, # 選択の状態を設定する
                           value = 2                    # ラジオボタンに割り付ける値の設定
                           )

        # ボタンの作成
        button = tk.Button(self.master, 
                           text = "ラジオボタンの選択を次へ",  # ボタンの表示名
                           command = self.button_click  # クリックされたときに呼ばれるメソッド
                           )

        # 配置
        radio0.pack()
        radio1.pack()
        radio2.pack()
        button.pack()

    def radio_click(self):
        # ラジオボタンの値を取得
        value = self.radio_value.get()
        print(f"ラジオボタンの値は {value} です")

    def button_click(self):
        # 選択されているラジオボタンを次に移動させる
        value = self.radio_value.get()
        self.radio_value.set((value + 1) % 3)

if __name__ == "__main__":
    root = tk.Tk()
    app = Application(master = root)
    app.mainloop()

(実行結果)

ポイント

  • ラジオボタンの値(選択されたときの識別番号)はIntVarクラスオブジェクトをRadiobuttonクラスのvariableオプションに設定する
  • 1つだけ選択される複数のラジオボタンには、それぞれ、同じIntVarクラスオブジェクトをvariableオプションに設定する
  • 各ラジオボタンの値(選択されたときの識別番号)はRadiobuttonクラスのvalueオプションに設定しておく
  • 選択されているラジオボタンの値(valueオプションで指定した値)は IntVarクラスオブジェクト.get() で行う
  • 選択されているラジオボタンを変更するには IntVarクラスオブジェクト.set() の引数にラジオボタンの値(valueオプションで指定した値)を指定します。

オプション

オプション名 説明
activebackground クリックされたときの背景色を指定します。
activeforeground クリックされたときの文字色(チェックマークを含む)を指定します。
anchor 文字の配置位置を指定します。
【設定値】tk.N, tk.S, tk.W, tk.E, tk.NW, tk.NE, tk.SW, tk.SE, tk.CENTER
【初期値】tk.CENTER
※width, heightを指定し、余白が生じている際に有効です。
background 通常時(クリックされていないとき)の背景色を指定します。(bgと同じ)
bd 枠線の太さを指定します。
ただし、初期状態では枠線が表示されていないため、reliefで枠線のスタイルを指定する必要があります。(borderwidthと同じ)
bg backgroundと同じ
bitmap モノクロのBitmapを指定します。
(参考)https://anzeljg.github.io/rin2/book2/2405/docs/tkinter/bitmaps.html
borderwidth bdと同じ
command ボタンがクリックされたときに呼び出すメソッドの名前を指定します。
compound 文字と画像の両方を表示する際に、文字に対して画像の表示位置を指定します。
【設定値】tk.LEFT, tk.RIGHT, tk.BOTTOM, tk.TOP, tk.CENTER
cursor ウィジェット上にマウスポインタがある際のカーソルの種類を指定します。
(参考)https://tkdocs.com/shipman/cursors.html
disabledforeground stateオプションで無効(DISABLED)に設定している際の文字色を設定します。
fg 表示する文字色を指定します。(foregroundと同じ)
font 表示する文字のフォントを指定します。
foreground fgと同じ
height ボタンの高さを文字数で指定します。
画像を配置した時は、画素数の指定になります。
highlightbackground
highlightcolor
highlightthickness
image 表示する画像を指定します。
indicatoron
justify 複数行の文字のときの、文字寄せ方向を指定します。
【設定値】左寄せ(tk.LEFT), 中央寄せ(tk.CENTER), 右寄せ(tk.RIGHT)
offrelief
overrelief ウィジェット上にマウスポインタがある際のスタイルを指定します。
【設定値】tk.RAISED, tk.GROOVE, tk.SUNKEN, tk.RIDGE, tk.FLAT
【初期値】tk.FLAT(枠線なし)
padx 文字の両側の隙間を指定します。
pady 文字の上下の隙間を指定します。
relief ボタンのスタイルを指定します。
【設定値】tk.RAISED, tk.GROOVE, tk.SUNKEN, tk.RIDGE, tk.FLAT
【初期値】tk.FLAT(枠線なし)
selectcolor チェックボックス(チェックのある四角)の背景色を指定します。
selectimage
state ウィジェットの有効/無効(操作できない状態)を指定します。
【設定値】tk.NORMAL, tk.DISABLED
【初期値】tk.NORMAL
takefocus
text 表示する文字を指定します。
textvariable
tristateimage
tristatevalue
underline 指定した順番(先頭から0始まり)の文字にアンダーラインを付加します。
value ラジオボタンの値(選択されたときの識別番号)
variable チェックの状態をBooleanVarクラスオブジェクトで指定します。
width ボタンの幅を文字数で指定します。
画像を配置した時は、画素数の指定になります。
wraplength 文字の折り返し幅を指定します。

メソッド

メソッド 説明
deselect() 選択状態のとき、同じvariableオプションを設定している他のラジオボタンも全て選択状態になります。(詳細不明。。)
flash() backgroundとactivebackgroundで交互に色を点滅させて表示します。
invoke() 選択状態にします。
select() 選択状態にします。

【Python/tkinter】Checkbutton(チェックボックス)

チェックボタン(チェックボックス)はCheckbuttonクラスによって作成します。

以下にサンプルを示します。

import tkinter as tk

class Application(tk.Frame):
    def __init__(self, master = None):
        super().__init__(master)

        self.master.title("チェックボックスの作成")       # ウィンドウタイトル
        self.master.geometry("300x100")                 # ウィンドウサイズ(幅x高さ)

        # チェックボックスの値
        self.check_value = tk.BooleanVar(value = True)  # 初期値を設定する場合
        #self.check_value = tk.BooleanVar()             # 初期値を設定しないとFlaseになる
        # チェックボックスの作成
        self.check = tk.Checkbutton(self.master, 
                           text = "チェックボックス",    # チェックボックスの表示名
                           command = self.check_click,  # クリックされたときに呼ばれるメソッド
                           variable = self.check_value  # チェックの状態を設定する
                           )

        # ボタンの作成
        button = tk.Button(self.master, 
                           text = "チェックを逆にする",  # ボタンの表示名
                           command = self.button_click  # クリックされたときに呼ばれるメソッド
                           )
        # 配置
        self.check.pack()
        button.pack()

    def check_click(self):
        # チェックの状態を取得(チェックされているときはTrue)
        value = self.check_value.get()
        print(f"チェックの状態は {value} です")

    def button_click(self):
        # チェックの状態を取得し逆に設定する
        value = self.check_value.get()
        self.check_value.set(not value)
        #以下のようにしても同じ
        #self.check.toggle()


if __name__ == "__main__":
    root = tk.Tk()
    app = Application(master = root)
    app.mainloop()

(実行結果)

ポイント

  • チェックボタンの値(チェックされている(True)/されていない(False))はBooleanVarクラスオブジェクトをCheckbuttonクラスのvariableオプションに設定する
  • チェックの状態の取得は BooleanVarクラスオブジェクト.get() で行う
  • チェックの状態の設定は BooleanVarクラスオブジェクト.set() の引数にTrue もしくは False を渡す

オプション

オプション名 説明
activebackground クリックされたときの背景色を指定します。
activeforeground クリックされたときの文字色(チェックマークを含む)を指定します。
anchor 文字の配置位置を指定します。
【設定値】tk.N, tk.S, tk.W, tk.E, tk.NW, tk.NE, tk.SW, tk.SE, tk.CENTER
【初期値】tk.CENTER
※width, heightを指定し、余白が生じている際に有効です。
background 通常時(クリックされていないとき)の背景色を指定します。(bgと同じ)
bd 枠線の太さを指定します。
ただし、初期状態では枠線が表示されていないため、reliefで枠線のスタイルを指定する必要があります。(borderwidthと同じ)
bg backgroundと同じ
bitmap モノクロのBitmapを指定します。
(参考)https://anzeljg.github.io/rin2/book2/2405/docs/tkinter/bitmaps.html
borderwidth bdと同じ
command ボタンがクリックされたときに呼び出すメソッドの名前を指定します。
compound 文字と画像の両方を表示する際に、文字に対して画像の表示位置を指定します。
【設定値】tk.LEFT, tk.RIGHT, tk.BOTTOM, tk.TOP, tk.CENTER
cursor ウィジェット上にマウスポインタがある際のカーソルの種類を指定します。
(参考)https://tkdocs.com/shipman/cursors.html
disabledforeground stateオプションで無効(DISABLED)に設定している際の文字色を設定します。
fg 表示する文字色を指定します。(foregroundと同じ)
font 表示する文字のフォントを指定します。
foreground fgと同じ
height ボタンの高さを文字数で指定します。
画像を配置した時は、画素数の指定になります。
highlightbackground
highlightcolor
highlightthickness
image 表示する画像を指定します。
indicatoron
justify 複数行の文字のときの、文字寄せ方向を指定します。
【設定値】左寄せ(tk.LEFT), 中央寄せ(tk.CENTER), 右寄せ(tk.RIGHT)
offvalue チェックが無い時の値をTrue, Falseで指定します。
【初期値】False
onvalue チェックがある時の値をTrue, Falseで指定します。
【初期値】True
overrelief ウィジェット上にマウスポインタがある際のスタイルを指定します。
【設定値】tk.RAISED, tk.GROOVE, tk.SUNKEN, tk.RIDGE, tk.FLAT
【初期値】tk.FLAT(枠線なし)
padx 文字の両側の隙間を指定します。
pady 文字の上下の隙間を指定します。
relief ボタンのスタイルを指定します。
【設定値】tk.RAISED, tk.GROOVE, tk.SUNKEN, tk.RIDGE, tk.FLAT
【初期値】tk.FLAT(枠線なし)
selectcolor チェックボックス(チェックのある四角)の背景色を指定します。
selectimage
state ウィジェットの有効/無効(操作できない状態)を指定します。
【設定値】tk.NORMAL, tk.DISABLED
【初期値】tk.NORMAL
takefocus
text 表示する文字を指定します。
textvariable
tristateimage
tristatevalue
underline 指定した順番(先頭から0始まり)の文字にアンダーラインを付加します。
variable チェックの状態をBooleanVarクラスオブジェクトで指定します。
width ボタンの幅を文字数で指定します。
画像を配置した時は、画素数の指定になります。
wraplength 文字の折り返し幅を指定します。

 

メソッド

メソッド 説明
deselect() チェックなし状態にします。
flash() backgroundとactivebackgroundで交互に色を点滅させて表示します。
invoke()
select() チェックあり状態にします。
toggle() チェックのあり/なしを逆に設定します。

 

【Python】本家ドキュメントリンク集

Pythonを勉強していて、何か分からなかった時、Googleで検索すればだいたいの情報は出てくると思いますが、とりあえず本家のページで確認して、正しい情報を知りたい!という事で、本家ページのリンク集です。

(随時更新予定です)

 

モジュール 概要
Python(日本語) Pythonのリファレンス、チュートリアルなど
math 数値の切り捨て、切り上げ、絶対値やSin, Cos, PI など
tkinter ウィンドウGUIのリファレンスチュートリアルなど
os 環境変数、ファイルパスの操作(ファイル名、ディレクトリの取得など)
matplotlib
データの可視化、数値データのグラフ表示、画像の表示など
numpy データ配列、乱数、FFT、行列演算など
PIL(pillow) 画像ファイルを開く、保存、画像データの変換など

【Python/tkinter】ファイルを開くダイアログボックスの表示

ファイルを開くダイアログボックスを表示するには、tkinter.filedialogモジュールのaskopenfilename()関数を使います。

以下にシンプルなサンプルプログラムを示します。

from tkinter import filedialog

filename = filedialog.askopenfilename()
print(filename)

(実行結果)

オプション

オプション名 説明
parent ダイアログを表示する親のウィンドウを指定します。
title ダイアログのタイトルを指定します。
initialdir 最初に表示されるディレクトリを指定します。
initialfile 最初に選択されているファイル名を指定します。
filetypes 選択可能なファイルの種類を設定します。
multiple 複数ファイルの選択を許可する場合はTrueを、そうでない場合はFalseを指定します。

(参考)

https://docs.python.org/ja/3/library/dialog.html?highlight=askopenfilename#module-tkinter.filedialog

サンプル

実際に、このダイアログを使用する場合には、title, initialdir, filetypesの3つは指定しておいた方が良いでしょう。

以下に私がよく使うパターンのサンプルを示します。

from tkinter import filedialog

filename = filedialog.askopenfilename(
    title = "画像ファイルを開く",
    filetypes = [("Image file", ".bmp .png .jpg .tif"), ("Bitmap", ".bmp"), ("PNG", ".png"), ("JPEG", ".jpg"), ("Tiff", ".tif") ], # ファイルフィルタ
    initialdir = "./" # 自分自身のディレクトリ
    )
print(filename)

(実行結果)

関連記事

【Python/tkinter】名前を付けて保存ダイアログボックスの表示

【Python/os】カレントディレクトリの取得/設定

カレントディレクトリを取得/設定するにはosモジュールgetcwd() および chdir() を用います。

getcwd カレントディレクトリの取得
chdir カレントディレクトリの設定

 

以下に、カレントディレクトリの取得/設定を繰り返したサンプルを示します。

import os

# カレントディレクトリの取得
current = os.getcwd()
print(current)

# カレントディレクトリの設定(一つ上)
os.chdir("../")

# カレントディレクトリの取得
current = os.getcwd()
print(current)

# カレントディレクトリの設定(直接パスの指定)
os.chdir("c:\\Temp")

# カレントディレクトリの取得
current = os.getcwd()
print(current)

(実行結果)

【Python/tkinter】メッセージボックス

メッセージボックスには、OKボタンが1つのメッセージボックスやOKボタン/Cancelボタンがあるものなど、いくつかのバリエーションがありますが、これらの種類は関数名で切り替えます。

 

まずは、以下のサンプルを実行して頂くと雰囲気がつかめると思います。

from tkinter import messagebox

ret = messagebox.showinfo(
    title = "タイトル",
    message = "showinfoで表示されるメッセージ")
print("showinfoの戻り値:\t", ret)

ret = messagebox.showwarning(
    title = "タイトル",
    message = "showwarningで表示されるメッセージ")
print("showwarningの戻り値:\t", ret)

ret = messagebox.showerror(
    title = "タイトル",
    message = "showerrorで表示されるメッセージ")
print("showerrorの戻り値:\t", ret)

ret = messagebox.askokcancel(
    title = "タイトル",
    message = "askokcancelで表示されるメッセージ")
print("askokcancelの戻り値:\t", ret)

ret = messagebox.askyesno(
    title = "タイトル",
    message = "askyesnoで表示されるメッセージ")
print("askyesnoの戻り値:\t", ret)

ret = messagebox.askretrycancel(
    title = "タイトル",
    message = "askretrycancelで表示されるメッセージ")
print("askretrycancelの戻り値:", ret)

ret = messagebox.askquestion(
    title = "タイトル",
    message = "askquestionで表示されるメッセージ")
print("askquestionの戻り値:\t", ret)

ret = messagebox.askyesnocancel(
    title = "タイトル",
    message = "askyesnocancelで表示されるメッセージ")
print("askyesnocancelの戻り値:", ret)

 

関数名 メッセージボックス 戻り値
showinfo ok
showwarning ok
showerror ok
askokcancel True, False
askyesno True, False
askretrycancel True, False
askquestion yes, no
askyesnocancel True, False, None

 

【Python/tkinter】ウィジェットの配置(pack)

ウィジェットを配置するには、pack,grid,placeの3つのメソッドがありますが、ここではpackについて説明します。(個人的にはpack, grid, placeのうち、packが一番使いやすいと思っています。)

packは、下図のように、ボタンやラベルなどのウィジェットを上、下、左、右方向に積み木のように、重ねて配置します。

 

以下に簡単なサンプルを示します。

import tkinter as tk

class Application(tk.Frame):
    def __init__(self, master = None):
        super().__init__(master)

        self.master.geometry("250x250") 

        # ボタンの作成
        button_top = tk.Button(self.master, text = "TOP", width = 8)
        button_bottom = tk.Button(self.master, text = "BOTTOM", width = 8)
        button_left = tk.Button(self.master, text = "LEFT", width = 8)
        button_right = tk.Button(self.master, text = "RIGHT", width = 8)

        # ウィジェットの配置
        button_top.pack(side = tk.TOP)
        button_bottom.pack(side = tk.BOTTOM)
        button_left.pack(side = tk.LEFT)
        button_right.pack(side = tk.RIGHT)

if __name__ == "__main__":
    root = tk.Tk()
    app = Application(master = root)
    app.mainloop()

(実行画面)

 

構文

ウィジェット.pack(オプション1 = 設定値, オプション2 = 設定値,・・・)

オプション

オプション名 説明
after すでに配置されているウィジェットの次にウィジェットを配置する
anchor sideで示した領域内のウィジェットの配置方向を指定します。
【設定値】tk.N, tk.S, tk.W, tk.E, tk.NW, tk.NE, tk.SW, tk.SE, tk.CENTER
【初期値設定値】tk.CENTER
before すでに配置されているウィジェットの前にウィジェットを配置する
expand ウィジェットを配置する領域を残りの領域全体に広げるかどうかを指定します。
【設定値】True, False
【初期値設定値】False
fill ウィジェットを領域の横、縦、または両方の方向の幅、高さに合わせてに大きくするか?設定します。
【設定値】tk.X, tk.Y, tk.BOTH, tk.NONE
【初期値設定値】tk.NONE
in_ ウィジェット作成時に親ウィジェットを指定せずに、配置時(pack時)に親ウィジェットを指定します。
ipadx ウィジェットの内側の横方向の隙間を設定します。
ipady ウィジェットの内側の縦方向の隙間を設定します。
padx ウィジェットの外側の横方向の隙間を設定します。
値で設定すると、両側の隙間を設定します。
タプルで(左, 右)のように設定すると、それぞれの隙間を指定できます。
pady ウィジェットの外側の縦方向の隙間を設定します。
値で設定すると、上下の隙間を設定します。
タプルで(上, 下)のように設定すると、それぞれの隙間を指定できます。
side ウィジェットの配置方向を、上、下、左、右の中から指定します。
【設定値】tk.TOP, tk.BOTTOM, tk.LEFT, tk.RIGHT
【初期値設定値】tk.TOP

 

side

sideではウィジェットの上下左右の配置方向を指定しますが、配置の順番が重要となります。

最初のプログラムの配置部分(packの部分)のプログラムは

# ウィジェットの配置
button_top.pack(side = tk.TOP)
button_bottom.pack(side = tk.BOTTOM)
button_left.pack(side = tk.LEFT)
button_right.pack(side = tk.RIGHT)

となっていますが、この結果は以下のような感じでした。

この配置の順番を入れ替えて、以下のようなプログラムにすると

# ウィジェットの配置
button_left.pack(side = tk.LEFT)
button_top.pack(side = tk.TOP)
button_right.pack(side = tk.RIGHT)
button_bottom.pack(side = tk.BOTTOM)

実行結果は

のようになり、バラバラな配置になります。
なぜ、このようになるのか?順を追って見ていきます。

最初にボタンを左側にpackしています。

button_left.pack(side = tk.LEFT)

この時点で、目には見えませんが、packした占有領域としては、親ウィジェットの左側の上から下までボタンの幅分、占有されています。

ボタン位置の上下方向はanchorで指定できますが、指定しない場合、初期値の中央(tk.CENTER)が適応されます。

次に配置されるウィジェットは、この残りの領域に対して配置されます。
つまり次のボタンを上側に配置以下のように配置すると、残りの領域の上側が占有されます。

button_top.pack(side = tk.TOP)

同様にして、次に右側に配置すると

button_right.pack(side = tk.RIGHT)

続いて下側

button_bottom.pack(side = tk.BOTTOM)

というように、pack()のsideでは残っている領域の上側、下側、左側、右側の上から下まで、もしくは左から右まで占有している事に注意が必要です。

 

anchor

anchorはsideとも似ているのですが、sideの説明で示した占有領域内(赤く囲った部分)の配置方向を方角を使って指定します。

これを踏まえた上で、以下のプログラムを実行してみます。

import tkinter as tk

class Application(tk.Frame):
    def __init__(self, master = None):
        super().__init__(master)

        self.master.geometry("250x250") 

        # ボタンの作成
        button_N = tk.Button(self.master, text = "N", width = 8)
        button_S = tk.Button(self.master, text = "S", width = 8)
        button_W = tk.Button(self.master, text = "W", width = 8)
        button_E = tk.Button(self.master, text = "E", width = 8)

        # ウィジェットの配置
        button_N.pack(anchor = tk.N)
        button_S.pack(anchor = tk.S)
        button_W.pack(anchor = tk.W)
        button_E.pack(anchor = tk.E)

if __name__ == "__main__":
    root = tk.Tk()
    app = Application(master = root)
    app.mainloop()

(実行結果)

すると、特に、tk.Sを指定した時に違和感がありますよね。
さらに、tk.Wとtk.Eの上下方向がズレてるし。。

これについても、packで占有される領域を示すと理解しやすくなります。

pack()では、sideオプションを指定しないとtk.TOPになるので、全て上側にウィジェットが積み重なります。
anchorオプションはあくまでも、占有領域内の配置方向を指定するので、side = tk.TOP のときは、上下方向の指定(tk.N, tk.S)はtk.CENTERと同様になります。

同様にして side = tk.LEFT もしくは side = tk.RIGHT のときは、左右方向の指定(tk.W, tk.E) も tk.CENTERと同様になります。

ただし、次に示す expand = True とした時は、上下、左右、斜め方向の指定が有効になります。

 

expand

expandは expand = Trueとした時、残っている領域全てを占有領域とします。

(サンプル)

import tkinter as tk

class Application(tk.Frame):
    def __init__(self, master = None):
        super().__init__(master)

        self.master.geometry("250x250") 

        # ボタンの作成
        button_top = tk.Button(self.master, text = "TOP", width = 8)
        button_center = tk.Button(self.master, text = "CENTER", width = 8)

        # ウィジェットの配置
        button_top.pack()
        button_center.pack(expand = True)

if __name__ == "__main__":
    root = tk.Tk()
    app = Application(master = root)
    app.mainloop()

(実行結果)

これも占有領域を書くと分かりやすいと思います。

2つ以上のウィジェットを expand = True にして配置すると、領域を均等分割して配置されます。

(サンプル)

import tkinter as tk

class Application(tk.Frame):
    def __init__(self, master = None):
        super().__init__(master)

        self.master.geometry("250x250") 

        # ボタンの作成
        button_top = tk.Button(self.master, text = "TOP", width = 8)
        button_center1 = tk.Button(self.master, text = "CENTER1", width = 8)
        button_center2 = tk.Button(self.master, text = "CENTER2", width = 8)

        # ウィジェットの配置
        button_top.pack()
        button_center1.pack(expand = True)
        button_center2.pack(expand = True)

if __name__ == "__main__":
    root = tk.Tk()
    app = Application(master = root)
    app.mainloop()

(実行結果)

これも占有領域を書いてみます。

 

fill

fillは、これまで説明してきた占有領域に対して、ウィジェットの幅、高さ、もしくは両方を合わせます。

(サンプル)

import tkinter as tk

class Application(tk.Frame):
    def __init__(self, master = None):
        super().__init__(master)

        self.master.geometry("250x250") 

        # ボタンの作成
        button_top = tk.Button(self.master, text = "TOP", width = 8)
        button_center = tk.Button(self.master, text = "CENTER", width = 8)

        # ウィジェットの配置
        button_top.pack()
        button_center.pack(expand = True, fill = tk.X)

if __name__ == "__main__":
    root = tk.Tk()
    app = Application(master = root)
    app.mainloop()

(実行結果)

fill = tk.Y のとき

fill = tk.BOTH

 

ipadx, ipady

ウィジェットの内側の隙間の量を指定します。

ipadxが横方向、ipadyが縦方向の隙間となります。

隙間を指定することで、ウィジェットの大きさも大きくなります。

(サンプル)

import tkinter as tk

class Application(tk.Frame):
    def __init__(self, master = None):
        super().__init__(master)

        self.master.geometry("250x250") 

        # ボタンの作成
        button_ipad0 = tk.Button(self.master, text = "ipadx = 0\nipady = 0")
        button_ipad  = tk.Button(self.master, text = "ipadx = 30\nipady = 10")

        # ウィジェットの配置
        button_ipad0.pack()
        button_ipad.pack(ipadx = 30, ipady = 10)

if __name__ == "__main__":
    root = tk.Tk()
    app = Application(master = root)
    app.mainloop()

(実行結果)

padx, pady

ウィジェットの外側の隙間の量を指定します。

padxが横方向、padyが縦方向の隙間となります。

(サンプル)

import tkinter as tk

class Application(tk.Frame):
    def __init__(self, master = None):
        super().__init__(master)

        self.master.geometry("250x250") 

        # ボタンの作成
        button1 = tk.Button(self.master, text = "Button1")
        button2 = tk.Button(self.master, text = "Button2")
        button3 = tk.Button(self.master, text = "Button3")
        button4 = tk.Button(self.master, text = "Button4")
        button_pad  = tk.Button(self.master, text = "padx = 30\npady = 10")

        # ウィジェットの配置
        button1.pack(side = tk.TOP, expand = True, fill = tk.BOTH)
        button4.pack(side = tk.BOTTOM, expand = True, fill = tk.BOTH)
        button2.pack(side = tk.LEFT, expand = True, fill = tk.BOTH)
        button_pad.pack(side = tk.LEFT, padx = 30, pady = 10)
        button3.pack(side = tk.LEFT, expand = True, fill = tk.BOTH)

if __name__ == "__main__":
    root = tk.Tk()
    app = Application(master = root)
    app.mainloop()

(実行結果)

after, before

ウィジェットの配置は順番が大事と説明してきましたが、すでに配置されているウィジェットの間に挿入して配置する場合に用います。

afterは指定したウィジェットの次にウィジェットを配置します。

beforeは指定したウィジェットの前にウィジェットを配置します。

(サンプル)

import tkinter as tk

class Application(tk.Frame):
    def __init__(self, master = None):
        super().__init__(master)

        self.master.geometry("250x250") 

        # ボタンの作成
        button1 = tk.Button(self.master, text = "Button1")
        button2 = tk.Button(self.master, text = "Button2")
        button3 = tk.Button(self.master, text = "Button3")
        button4 = tk.Button(self.master, text = "Button4")
        button5 = tk.Button(self.master, text = "Button5")

        button2_after = tk.Button(self.master, text = "Button2_After")
        button5_before = tk.Button(self.master, text = "Button5_Before")


        # ウィジェットの配置
        button1.pack()
        button2.pack()
        button3.pack()
        button4.pack()
        button5.pack()
        # すでに配置されているウィジェットの次に配置する
        button2_after.pack(after = button2)
        # すでに配置されているウィジェットの前に配置する
        button5_before.pack(before = button5)

if __name__ == "__main__":
    root = tk.Tk()
    app = Application(master = root)
    app.mainloop()

(実行結果)

in_

ウィジェット作成時に親ウィジェットを指定せずに、配置時(pack時)に親ウィジェットを指定します。

(サンプル)

import tkinter as tk

class Application(tk.Frame):
    def __init__(self, master = None):
        super().__init__(master)

        self.master.geometry("250x250") 

        # 左側のフレーム
        frame_left = tk.Frame(self.master)
        # 右側のフレーム
        frame_right = tk.Frame(self.master)

        # ボタンの作成
        button1 = tk.Button(frame_left, text = "Button1")
        button2 = tk.Button(text = "Button2") # ここでは親のウィジェットを指定していない

        # ウィジェットの配置
        button1.pack()
        button2.pack(in_ = frame_right) # ここでは親のウィジェットを指定

        # フレームの配置
        frame_left.pack(side = tk.LEFT, expand = True)
        frame_right.pack(side = tk.LEFT, expand = True)

if __name__ == "__main__":
    root = tk.Tk()
    app = Application(master = root)
    app.mainloop()

(実行結果)

まとめ

ここまで、ウィジェットの配置は順番が重要だと説明してきましたが、実際には1つの親ウィジェットに、様々なオプションを駆使してウィジェットを配置するのは、かなり困難です。

そのため、いくつかのフレーム(Frame)を使って大枠を作成し、各フレームにウィジェットを配置すると比較的簡単に配置できます。

そこで、私がC#では良く作っていたウィンドウのレイアウトを、フレームをいくつか使いサンプルを作成してみました。

(サンプルプログラム)

import tkinter as tk
from tkinter import filedialog
import os


class Application(tk.Frame):
    def __init__(self, master = None):
        super().__init__(master)

        # ウィンドウタイトル
        self.master.title("ウィジェット配置サンプル(packを使用)")

        self.master.geometry("500x300") 

        # メニューの作成
        self.create_menu()
        # ツールバーの作成
        self.create_tool_bar()
        # ステータスバーの作成
        self.create_status_bar()
        # サイドパネル
        self.create_side_panel()

        # 残りの領域にキャンバスを作成
        canvas = tk.Canvas(self.master, background="#008080")
        canvas.pack(expand=True,  fill=tk.BOTH)

    def create_menu(self):
        ''' メニューの作成'''
        menu_bar = tk.Menu(self)
 
        file_menu = tk.Menu(menu_bar, tearoff = tk.OFF)
        menu_bar.add_cascade(label="ファイル", menu = file_menu) 

        file_menu.add_command(label = "開く", command = self.menu_open_click, accelerator = "Ctrl+O")
        file_menu.add_separator() # セパレータ
        file_menu.add_command(label = "終了", command = self.master.destroy)
        # ショートカットの設定
        menu_bar.bind_all("", self.menu_open_click)

        # 親のメニューに設定
        self.master.config(menu = menu_bar)

    def menu_open_click(self, event=None):
        ''' ファイルを開く'''

        # ファイルを開くダイアログ
        filename = tk.filedialog.askopenfilename(
            initialdir = os.getcwd() # カレントディレクトリ
            )
        print(filename)

    def create_tool_bar(self):
        ''' ツールバー'''

        frame_tool_bar = tk.Frame(self.master, borderwidth = 2, relief = tk.SUNKEN)

        button1 = tk.Button(frame_tool_bar, text = "1", width = 2)
        button2 = tk.Button(frame_tool_bar, text = "2", width = 2)
        button3 = tk.Button(frame_tool_bar, text = "3", width = 2)

        button1.pack(side = tk.LEFT)
        button2.pack(side = tk.LEFT)
        button3.pack(side = tk.LEFT)

        frame_tool_bar.pack(fill = tk.X)

    def create_status_bar(self):
        '''ステータスバー'''
        frame_status_bar = tk.Frame(self.master, borderwidth = 2, relief = tk.SUNKEN)

        self.label1 = tk.Label(frame_status_bar, text = "ステータスラベル1")
        self.label2 = tk.Label(frame_status_bar, text = "ステータスラベル2")

        self.label1.pack(side = tk.LEFT)
        self.label2.pack(side = tk.RIGHT)

        frame_status_bar.pack(side = tk.BOTTOM, fill = tk.X)

    def create_side_panel(self):
        '''サイドパネル'''
        side_panel = tk.Frame(self.master, borderwidth = 2, relief = tk.SUNKEN)

        button1 = tk.Button(side_panel, text = "ボタン1", width = 15)
        button2 = tk.Button(side_panel, text = "ボタン2", width = 15)

        button1.pack()
        button2.pack()

        side_panel.pack(side = tk.RIGHT, fill = tk.Y)


if __name__ == "__main__":
    root = tk.Tk()
    app = Application(master = root)
    app.mainloop()

【Python/tkinter】Button(ボタン)

tkinterでボタンの作成のサンプルを以下に示します。

import tkinter as tk

class Application(tk.Frame):
    def __init__(self, master = None):
        super().__init__(master)

        self.master.title("ボタンの作成")     # ウィンドウタイトル
        self.master.geometry("300x100")       # ウィンドウサイズ(幅x高さ)

        #--------------------------------------------------------
        # ボタンの作成
        button = tk.Button(self.master, 
                           text = "ボタン",             # ボタンの表示名
                           command = self.button_click  # クリックされたときに呼ばれるメソッド
                           )
        button.pack()
        #--------------------------------------------------------
    def button_click(self):
        '''クリックされたときに呼ばれるメソッド'''
        print("ボタンがクリックされた")

if __name__ == "__main__":
    root = tk.Tk()
    app = Application(master = root)
    app.mainloop()

(実行画面)

構文

ボタンオブジェクト = tk.Button(親ウィジェット, オプション1 = 設定値, オプション2 = 設定値,・・・)

オプション

オプション名 説明
activebackground クリックされたときの背景色を指定します。
activeforeground クリックされたときの文字色を指定します。
anchor 文字の配置位置を指定します。
【設定値】tk.N, tk.S, tk.W, tk.E, tk.NW, tk.NE, tk.SW, tk.SE, tk.CENTER
background 背景色を指定します。
bd 枠線の太さを指定します。
bg 通常時の背景色を指定します。
bitmap モノクロのBitmapを指定します。
(参考)https://anzeljg.github.io/rin2/book2/2405/docs/tkinter/bitmaps.html
borderwidth bdと同じ
command ボタンがクリックされたときに呼び出すメソッドの名前を指定します。
compound 文字と画像の両方を表示する際に、文字に対して画像の表示位置を指定します。
【設定値】tk.LEFT, tk.RIGHT, tk.BOTTOM, tk.TOP, tk.CENTER
cursor ウィジェット上にマウスポインタがある際のカーソルの種類を指定します。
(参考)https://tkdocs.com/shipman/cursors.html
default
disabledforeground stateオプションで無効(DISABLED)に設定している際の文字色を設定します。
fg 表示する文字色を指定します。(foregroundと同じ)
font 表示する文字のフォントを指定します。
foreground
height ボタンの高さを文字数で指定します。
画像を配置した時は、画素数の指定になります。
highlightbackground
highlightcolor
highlightthickness
image 表示する画像を指定します。
justify 複数行の文字のときの、文字寄せ方向を指定します。
【設定値】左寄せ(tk.LEFT), 中央寄せ(tk.CENTER), 右寄せ(tk.RIGHT)
overrelief
padx 文字の両側の隙間を指定します。
pady 文字の上下の隙間を指定します。
relief ボタンのスタイルを指定します。
【設定値】tk.RAISED, tk.GROOVE, tk.SUNKEN, tk.RIDGE, tk.FLAT
repeatdelay
repeatinterval
state
takefocus
text 表示する文字を指定します。
textvariable StringVarクラスオブジェクトを指定し、ボタンの文字列を指定します。
underline 指定した順番(先頭から0始まり)の文字にアンダーラインを付加します。
width ボタンの幅を文字数で指定します。
wraplength 文字の折り返し幅を指定します。

 

サンプルプログラム

評価に用いたプログラムを以下に示します。

import tkinter as tk

class Application(tk.Frame):
    def __init__(self, master = None):
        super().__init__(master)

        self.master.title("ボタンの作成(Windowsスタイル)")     # ウィンドウタイトル
        self.master.geometry("580x580")       # ウィンドウサイズ(幅x高さ)

        # ボタンの作成
        button1 = tk.Button(self.master, text = "ボタン")
        # クリックイベントの指定
        button2 = tk.Button(self.master, text = "クリック", 
                            command = self.button_click # クリック時に呼び出されるメソッド名
                            )
        # 無効ボタン
        button3 = tk.Button(self.master, text = "無効ボタン",
                            state = tk.DISABLED # 無効:tk.DISABLED 有効:tk.NORMAL
                            )
        # ボタンサイズ
        button4 = tk.Button(self.master, text = "ボタンサイズ", 
                            width = 20, height = 2      # サイズは文字数で指定
                            )
        # フォントサイズ
        button5 = tk.Button(self.master, text = "フォントサイズ", 
                            font = ("", 18) # フォントサイズの変更
                            )
        # ボタンスタイル
        button6 = tk.Button(self.master, text = "RAISED", 
                            relief = tk.RAISED      
                            )
        button7 = tk.Button(self.master, text = "GROOVE", 
                            relief = tk.GROOVE      
                            )
        button8 = tk.Button(self.master, text = "SUNKEN", 
                            relief = tk.SUNKEN      # 凹んだ状態(クリックはできる)
                            )
        button9 = tk.Button(self.master, text = "RIDGE", 
                            relief = tk.RIDGE      
                            )
        button10 = tk.Button(self.master, text = "FLAT", 
                            relief = tk.RIDGE      
                            )

        # 文字の位置
        button11 = tk.Button(self.master, text = "NW", 
                            width = 10, height = 2,
                            anchor = tk.NW 
                            )
        button12 = tk.Button(self.master, text = "N", 
                            width = 10, height = 2,
                            anchor = tk.N
                            )
        button13 = tk.Button(self.master, text = "NE", 
                            width = 10, height = 2,
                            anchor = tk.NE
                            )
        button14 = tk.Button(self.master, text = "W", 
                            width = 10, height = 2,
                            anchor = tk.W
                            )
        button15 = tk.Button(self.master, text = "CENTER", 
                            width = 10, height = 2,
                            anchor = tk.CENTER
                            )
        button16 = tk.Button(self.master, text = "E", 
                            width = 10, height = 2,
                            anchor = tk.E
                            )
        button17 = tk.Button(self.master, text = "SW", 
                            width = 10, height = 2,
                            anchor = tk.SW
                            )
        button18 = tk.Button(self.master, text = "S", 
                            width = 10, height = 2,
                            anchor = tk.S
                            )
        button19 = tk.Button(self.master, text = "SE", 
                            width = 10, height = 2,
                            anchor = tk.SE
                            )

        # 文字の左寄せ
        button20 = tk.Button(self.master, text = "o文字左寄せo\noo文字左寄せoo\nooo文字左寄せooo", 
                            width = 25, height = 3,
                            justify = tk.LEFT
                            )       
        
        # 文字の中央寄せ
        button21 = tk.Button(self.master, text = "o文字中央寄せo\noo文字中央寄せoo\nooo文字中央寄せooo", 
                            width = 25, height = 3,
                            justify = tk.CENTER
                            )

        # 文字の右寄せ
        button22 = tk.Button(self.master, text = "o文字右寄せo\noo文字右寄せoo\nooo文字右寄せooo", 
                            width = 25, height = 3,
                            justify = tk.RIGHT
                            )

        # 枠線幅
        button23 = tk.Button(self.master, text = "枠線幅2", 
                            bd = 2
                            )
        button24 = tk.Button(self.master, text = "枠線幅4", 
                            bd = 4
                            )
        button25 = tk.Button(self.master, text = "枠線幅6", 
                            bd = 6
                            )
        # 横方向のパディング(文字列の両側の隙間)
        button26 = tk.Button(self.master, text = "padx=2", 
                            padx = 2
                            )
        button27 = tk.Button(self.master, text = "padx=10", 
                            padx = 10
                            )
        button28 = tk.Button(self.master, text = "padx=20", 
                            padx = 20
                            )
        # 縦方向のパディング(文字列の上下の隙間)
        button29 = tk.Button(self.master, text = "pady=2", 
                            pady = 2
                            )
        button30 = tk.Button(self.master, text = "pady=10", 
                            pady = 10
                            )
        button31 = tk.Button(self.master, text = "pady=20", 
                            pady = 20
                            )
        # 横、縦方向のパディング組み合わせ
        button32 = tk.Button(self.master, text = "padx=20\npady=10", 
                            padx = 20, pady = 10
                            )
        # wraplength
        button33 = tk.Button(self.master, text = "wraplength文字の折り返し幅", 
                            wraplength = 60
                            )

        # 色の変更
        button34 = tk.Button(self.master, text = "色の変更", 
                            bg = "#00ff00", # 通常時の背景色
                            fg = "#ff00ff", # 通常時の文字色
                            activebackground = "#ff0000", # クリックされた時の背景色
                            activeforeground = "#0000ff"  # クリックされた時の文字色
                            )
        # ハイライトカラー
        button35 = tk.Button(self.master, text = "ハイライトカラー",  # 無効?
                            highlightcolor = "#ffff00" # ハイライトカラー
                            )
        # アンダーライン(1文字)
        button36 = tk.Button(self.master, text = "アンダーライン(1文字)", 
                            underline = 2      # 2番目(0始まり)の文字にアンダーライン、-1で無し
                            ) 
        # アンダーライン(全文字)
        button37 = tk.Button(self.master, text = "アンダーライン(全文字)", 
                            font = ("", 9, "underline")      # 文字全体のアンダーラインはfontで指定
                            ) 

        # ボタンの配置
        button1.grid(row=0, column=0)
        button2.grid(row=0, column=1)
        button3.grid(row=0, column=2)

        button4.grid(row=1, column=0)
        button5.grid(row=1, column=1)

        button6.grid(row=2, column=0)
        button7.grid(row=2, column=1)
        button8.grid(row=2, column=2)
        button9.grid(row=3, column=0)
        button10.grid(row=3, column=1)

        button11.grid(row=4, column=0)
        button12.grid(row=4, column=1)
        button13.grid(row=4, column=2)
        button14.grid(row=5, column=0)
        button15.grid(row=5, column=1)
        button16.grid(row=5, column=2)
        button17.grid(row=6, column=0)
        button18.grid(row=6, column=1)
        button19.grid(row=6, column=2)

        button20.grid(row=7, column=0)
        button21.grid(row=7, column=1)
        button22.grid(row=7, column=2)

        button23.grid(row=8, column=0)
        button24.grid(row=8, column=1)
        button25.grid(row=8, column=2)

        button26.grid(row=9, column=0)
        button27.grid(row=9, column=1)
        button28.grid(row=9, column=2)

        button29.grid(row=10, column=0)
        button30.grid(row=10, column=1)
        button31.grid(row=10, column=2)
        button32.grid(row=11, column=0)

        button33.grid(row=12, column=0)
        button34.grid(row=12, column=1)
        button35.grid(row=12, column=2)

        button36.grid(row=13, column=0)
        button37.grid(row=13, column=1)

    def button_click(self):
        print("ボタンがクリックされた")

if __name__ == "__main__":
    root = tk.Tk()
    app = Application(master = root)
    app.mainloop()

【Python】リストの作成、追加、削除、挿入など

C#では、配列とリストは明確に別物なのですが、Pythonでは配列と言いながらリストの事を指している場合が多いようです。

Pythonには型宣言が無いので、C#で言うところのobjectクラスのリスト(List<object>)にイメージが近く、各要素には、数値や文字列などの、ごちゃまぜもできます。

以下のコード例は、上から順に実行した場合です。

リストの宣言

角カッコ([])で変数がリストである事を宣言します。

list_data = []

リストの初期化

角カッコ([])の中に要素をカンマ(,)で区切って初期化します。
各要素の型はごちゃまぜにできます。

list_data = [0, "abc", 2, 3, "def", 4]
print(list_data)

実行結果

[0, ‘abc’, 2, 3, ‘def’, 4]

要素の追加

append(追加する要素)で、リストの最後に要素が追加されます。

list_data.append(5)
print(list_data)

実行結果

[0, ‘abc’, 2, 3, ‘def’, 4, 5]

リストにリストを追加

元のリスト.extend(追加するリスト)で、元のリストに別のリストを追加し、追加されたリストは元のリストに格納されます

list_data = [0, 'abc', 2, 3, 'def', 4, 5]
list_ext  = ['ghi', 6, 7, 8, 9, 10, 11, 12]
list_data.extend(list_ext)
print(list_data)

実行結果

[0, ‘abc’, 2, 3, ‘def’, 4, 5, ‘ghi’, 6, 7, 8, 9, 10, 11, 12]

指定した要素のindex番号を取得

index(番号を取得する要素)で、要素のindex番号を取得します。
指定した要素が複数ある場合は、最初に見つけた要素のindex番号を取得します。

print(list_data.index('ghi'))

実行結果

7

要素の番号を指定して削除

del リスト[削除するindex番号]で、要素を削除します。

del list_data[list_data.index('ghi')]
print(list_data)

実行結果

[0, ‘abc’, 2, 3, ‘def’, 4, 5, 6, 7, 8, 9, 10, 11, 12]

要素の番号を指定して要素を抜き出す(削除する)

pop(削除する要素のindex番号)で、要素を削除し、削除した要素を返します。

ret = list_data.pop(1)
print(ret)
print(list_data)

実行結果

abc

[0, 2, 3, ‘def’, 4, 5]

要素を指定して削除

remove(削除する要素)で、要素を削除します。
指定した要素が複数ある場合は、最初に見つけた要素を削除します。

list_data.remove("def")
print(list_data)

実行結果

[0, 2, 3, 4, 5]

要素の挿入

insert(挿入する場所のindex番号, 挿入する要素)で、要素を挿入します。

list_data.insert(1, 10)
print(list_data)

実行結果

[0, 10, 2, 3, 4, 5]

要素があるかどうか?

要素 in リストで、要素があれば True、なければ Falseが返ります。

print(10 in list_data)
print(11 in list_data)

実行結果

True
False

要素のindex番号を取得

index(番号を取得する要素)で、要素のindex番号を取得します。
指定した要素が複数ある場合は、最初に見つけた要素のindex番号を取得します。

print(list_data.index(10))

実行結果

1

リストの要素数を取得

len(リスト)で、要素の個数を取得します。

print(len(list_data))

実行結果

6

指定した要素の個数を取得

count(要素)で、リスト中の要素の個数を取得します。

list_data = [0, 1, "abc, 2, 3, "abc", 4, 5]
print(list_data.count("abc"))

実行結果

2

 

【Python】数値演算

Pythonにおいて、足し算、引き算、掛け算、割り算などの数値演算は、以下のようになります。

 

演算の種類 演算子 計算例 答え
足し算 + 2 + 3 5
引き算 7 – 4 3
掛け算 * 3 * 6 18
割り算 / 7 / 2 3.5
商(小数以下切り捨て) // 7 // 2 3
余り % 7 % 2 1
べき乗 ** 2 ** 8 256

 

特に、割り算は整数で割っても答えが小数で返されるのは、他のC言語やC#の仕様とは異なるので、注意が必要です。切り捨ての演算(//)も覚えておきたいところですね。

 

画像処理の場合、4の倍数の計算とかもよくやっているのですが、以下のような計算になります。

(計算例)638を超える4の倍数の値の計算

>>> (638 + 3) // 4 * 4
640

【Python】importとは?

Pythonを勉強し始めると、いきなり

import numpy as np

とかが出てきて、ナニコレ?ってなるのですが、C言語で言うところのヘッダファイル(*.h)のインクルードにイメージが近いと思います。

Pythonでは、import とすることでモジュール(ライブラリ)を使用できるようにしています。

 

書式的には

import 「モジュール名 もしくは Pythonファイル名の拡張子なし」 as 「代替名」

となります。

 

そのため、最初のプログラム例では、numpyモジュールを np として用いる宣言をしています。

(使用例)

import numpy as np

data = np.array([0,1,2])
print(data)

as以降の代替名の部分は無くても構いません。

import numpy

data = numpy.array([0,1,2])
print(data)

また、これとは別に、似た感じで

from matplotlib import pyplot

というのも登場しますが、この書式的には

from 「モジュール名」 import 「クラス名 もしくは 関数名」

となります。

そのため、上記の例では、 matplotlibモジュールの中からpyplotだけを用いる事を宣言しています。

【Python】Visual Studioのインデントを自動に設定する

Visual StudioでPythonのプログラムを書くとき、for文やif文など、インデントが必要な場合、改行しても自動でインデントしてくれないので、自動でインデントするための設定を行います。

 

設定方法は、Visual Studioのメニューから、ツール→オプションでオプション設定画面を開きます。

 

 

オプション画面の テキストエディター → Python → タブ を選択し、インデントスマート を選択し、OKボタンをクリックします。

これで、自動でインデントしてくれます。