LoginSignup
3
8

tkinterでカレンダー選択から日付情報を得るダイアログを作成する。

Last updated at Posted at 2023-07-31

Abstract

pythonで簡単なGUIを作成する機会があり、その際に日付の入力欄を作る必要があった。要件としては、入力欄は基本的には手打ちだが、カレンダー選択による自動入力機能を付けてほしいとうことだった。Webのノリで簡単にできるだろうと高をくくっていたら意外とはまってしまったので、誰の役に立つかわからないが残しておくことにする。

実装

calenderdialog.py
import tkinter
from tkinter.simpledialog import Dialog
from tkcalendar import Calendar

class CalenderDialog(Dialog):
    date: str
    def __init__(self, master: tkinter.Tk, title=None) -> None:
        self.date = ""
        super().__init__(parent=master, title=title)
        
    #//Override
    def body(self, master) -> None:
        self.calendar = Calendar(master, showweeknumbers=False, date_pattern="yyyy/mm/dd")
        self.calendar.grid(sticky="w", row=0, column=0)
        
    #//Override
    def apply(self) -> None:
        self.date = self.calendar.get_date()
        print(self.date)
        
    def get_date(self) -> str:
        return self.date

いろいろ方法はあると思うが、既存のダイアログをカスタマイズして、カレンダーから情報を返す方法が簡単そうだったので今回はこの方法をとる。具体的にはtkinter.simpledialog.Dialogを継承し、下記メンバを2つオーバライドすることで簡単に実現できる。

body() ダイアログの本体を表示するメソッド
apply() OKボタンが押されたときに実行するメソッド

body()でカレンダーを表示させ、OKボタンをトリガーに日付の値をself.dateへ格納する。
公式いわくOKやCancelの表示が気に食わないひとはbuttonbox()をオーバーライドしてカスタマイズしてとのこと。

テスト

test.py
#//自作したDialog
from calenderdialog import CalenderDialog

import tkinter
from tkinter import Frame
from tkinter import Label
from tkinter import Entry
from tkinter import Button

class Test:
    def __init__(self):
        self.root = tkinter.Tk()
        self.root.geometry("200x200")
        fream = Frame(self.root, bd=4, relief="groove")
        label = Label(fream, text="Date")
        label.grid(padx=2, sticky="w", row=0, column=0)
        self.entry = Entry(fream, width=20)
        self.entry.grid(sticky="w", row=1, column=0)
        button = Button(fream,text="get",width=4,command=self.get_date)
        button.grid(sticky="w", row=1, column=1)
        fream.pack()
        
    def get_date(self) -> None:
        dialog = CalenderDialog(self.root, title="calendar")
        date = dialog.get_date()
        if date != "":
            self.entry.delete(0, tkinter.END)
            self.entry.insert(0,date)
            
    def run(self):
        self.root.mainloop()

if __name__ == "__main__":
    test = Test()
    test.run()

実行可能なテストコードを示す。
手打ち入力とカレンダー入力に対応した入力欄を作ることができた。

CalenderDialog.gif

参考

Tkinter ダイアログ

3
8
3

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
8