【Python tkinter】メニューバー(Menu)の作成方法

時計 2020.05.04 / 時計

【Python tkinter】メニューバー(Menu)の作成方法

GUIアプリケーションでは必ずと言っていいほどメニューバーは使われています。

もちろんPythonのGUI作成ライブラリであるTkinterでもメニューバー作成を簡単に作成することができます。

今回はGUIアプリケーションにメニューバーを実際に付け加えながら、メニューバーの作成方法を解説していきます。

メニューバーを追加するアプリ紹介

下記記事で作成した、「OUTLOOKから添付ファイルを保存するアプリ」にメニューバーを今回は追加していきます。

現在のGUI画面は以下のようになっています。

outlookプログラムのGUI画面

このGUI画面にメニューバーを追加して、より一層デスクトップアプリケーションのようにしていきます。

menubarの大元(コンテナ)の作成と設置

# menubarの大元(コンテナ)の作成と設置
menubar = tk.Menu(root)
root.config(menu=menubar)

tkinterのメニューバーは、いわば階層構造になっています。

その階層構造の大元をtk.Menu()で作成します。ここで作成したMenuウィジェットの中にメニュー項目を入れ込んでいきます。

なので最初に作るMenuウィジェットはメニューバーのコンテナと言えるでしょう。

tk.Menu()の引数にはメインウィンドウを指定します。

そしてこの大元(コンテナ)はroot.config(menu=コンテナ名)で設置されます。

各種メニューの作成

# menubarを親として設定メニューを作成と表示
setting_menu = tk.Menu(menubar, tearoff=0)
menubar.add_cascade(label='設定', menu=setting_menu)

# menubarを親としてヘルプメニューを作成と表示
help_menu = tk.Menu(menubar, tearoff=0)
menubar.add_cascade(label='ヘルプ', menu=help_menu)

メニューバーに設置するメニューをtk.Menu()で作成します。これはメニューバーの大元(コンテナ)を作成するときと同じですね。

違う箇所としては、引数にメニューバーの大元(コンテナ)を指定することです。
引数に指定された場所に作成したメニューを入れ込むイメージです。

また第2パラメーターにtearoff=0が指定されていますが、これによりメニューに表示される切り取り線をなくしています。

コンテナに入れ込んだメニューを表示させるためにadd_cascade()メソッドを使用します。

引数内のlabelでは表示する名前を設定できます。

各種メニューを作成・表示することにより以下のようなGUI画面になります。

Tkinter:GUI画面にメニューバーを追加

設定メニューにプルダウンメニューを追加

# 設定メニューにプルダウンメニューを追加
setting_menu.add_command(label='環境設定')
setting_menu.add_command(label='終了')

# ヘルプメニューにプルダウンメニューを追加
help_menu.add_command(label='FAQ')

各種メニューにプルダウンメニューを追加する場合はadd_commandメソッドを使用します。

コンテナ内に入れ込んだMenuウィジェットにぶら下がるプルダウンメニューを作れます。

Tkinter:GUI画面にプルダウンメニューを追加

labelで表示する名前、commandでボタンを押下されたときに呼び出す関数を割り当てすることができます。

まとめ

これでGUI画面にメニューバーを追加することができました。

以下にメニューバーを追加したアプリのソースコードを記します。

import win32com.client
import datetime
import os
import tkinter as tk
import tkinter.ttk as ttk
from tkinter import filedialog
from tkinter import messagebox
import os.path

# 保存先フォルダーを指定し、entry_folderにセットする
def ask_folder():
    fld = filedialog.askdirectory()
    entry_folder.insert(tk.END, fld)

def click_execute():
    # Outlookからメール情報を取得
    outlook = win32com.client.Dispatch("Outlook.Application").GetNamespace("MAPI")
    if not entry_outlook.get():
        # 受信フォルダのメールを取得
        folders = outlook.GetDefaultFolder(6)
    else:
        # 指定されたメールフォルダのメールを取得
        folders = outlook.GetDefaultFolder(6).Folders[entry_outlook.get()]
    # メールフォルダ内のメールにアクセス
    mails=folders.Items

    #添付ファイルの保管用フォルダ作成
    newfolder_path = entry_folder.get() + '/Outlook_test'
    # 作成フォルダが存在するかの確認
    if os.path.isdir(newfolder_path) == False:
        # フォルダがなければ作成する
        os.makedirs(newfolder_path)

    # 絞り込み日程の取得
    startdate = datetime.datetime.strptime(entry_start.get(), '%Y/%m/%d')
    enddate = datetime.datetime.strptime(entry_end.get(), '%Y/%m/%d')


    #メール情報を1件1件取得し、添付ファイルがあれば保存する
    for mail in mails:
        RT=mail.ReceivedTime
        period = datetime.datetime(RT.year ,RT.month, RT.day, RT.hour, RT.minute, RT.second)
        if startdate <= period <= enddate:
            if mail.Attachments.Count > 0:
                myDate = RT.strftime("%Y/%m/%d")
                myDate = myDate.replace("/","-")
                datefolder_path = newfolder_path + '\\' + myDate
                if os.path.isdir(datefolder_path) == False:
                    os.makedirs(datefolder_path)
                for myAttachment in mail.Attachments:
                    folder_path = datefolder_path + '\\' + myAttachment.FileName
                    if os.path.isfile(folder_path) == False:
                        myAttachment.SaveAsFile(folder_path)
    messagebox.showinfo("完了","添付ファイルをダウンロードしました")
# メインウィンドウの設定
root = tk.Tk()
root.title("OUTLOOK操作")
root.geometry("600x300")

### menubarの作成と設置 ###
# menubarの大元(コンテナ)の作成と設置
menubar = tk.Menu(root)
root.config(menu=menubar)

# menubarを親として設定メニューを作成と表示
setting_menu = tk.Menu(menubar, tearoff=0)
menubar.add_cascade(label='設定', menu=setting_menu)

# menubarを親としてヘルプメニューを作成と表示
help_menu = tk.Menu(menubar, tearoff=0)
menubar.add_cascade(label='ヘルプ', menu=help_menu)

# 設定メニューにプルダウンメニューを追加
setting_menu.add_command(label='環境設定')
setting_menu.add_command(label='終了')

# ヘルプメニューにプルダウンメニューを追加
help_menu.add_command(label='FAQ')

### menubarの終了 ###

# メインフレームの作成と設置
frame = ttk.Frame(root)
frame.grid(column=0, row=0, sticky=tk.NSEW, padx=5, pady=10)

# 各種ウィジェットの作成
label_start = ttk.Label(frame, text="集計開始日(yyyy/mm/dd):")
entry_start = ttk.Entry(frame)
label_end = ttk.Label(frame, text="集計終了日(yyyy/mm/dd):")
entry_end = ttk.Entry(frame)
label_folder = ttk.Label(frame, text="出力先フォルダ:")
entry_folder = ttk.Entry(frame, width=50)
button_folder = ttk.Button(frame, text="参照", command=ask_folder)
label_outlook = ttk.Label(frame, text="OUTLOOK受信フォルダ名:")
entry_outlook = ttk.Entry(frame)
button_execute = ttk.Button(frame, text="実行", command=click_execute)

# 各種ウィジェットの設置
label_start.grid(row=0, column=0, padx=10, pady=2)
entry_start.grid(row=0, column=1, sticky=tk.W)
label_end.grid(row=1, column=0, padx=10, pady=2)
entry_end.grid(row=1, column=1, sticky=tk.W)
label_folder.grid(row=2, column=0, padx=10,pady=2, sticky=tk.E)
entry_folder.grid(row=2, column=1,sticky=tk.W)
button_folder.grid(row=2, column=2, sticky=tk.E)
label_outlook.grid(row=3, column=0, padx=10, pady=2, sticky=tk.E)
entry_outlook.grid(row=3, column=1, sticky=tk.W)
button_execute.grid(row=4, column=1, pady=10)

dt_now = datetime.datetime.now()
dt_now = dt_now.strftime("%Y/%m/%d")
entry_end.insert(tk.END, dt_now)

root.mainloop()