概要
下記サイトのPythonのtkinterで作成されたカレンダーを利用したいのですが、
クリックされた年月日の取得で躓いています。
python tkinter カレンダーの月めくり処理を実装する(カレンダー編③)
http://memopy.hatenadiary.jp/entry/2017/06/18/100406
memopy様、アップしていただきありがとうございます。
引用させていただきます。
実現したいこと
カレンダーの日付ボタンをクリックすると
クリックされたボタンのテキストを取得し、
トップに表示中の西暦と月を連結して
'20200112'のような8桁の年月日データを取り出したいと思っています。
(ゆくゆくはこのイベントで
選択された日の詳細データを取得する処理をさせる予定です。)
やってみたこと
クリックされたボタンのテキストを取得する関数を書き、
ボタンを作成するクラスとバインドさせることには成功したのですが、
トップに表示中の西暦と月の両テキストを取得するためには
どうしたらよいのかがわかりません。
以下、私が新たに記述した関数です。
Python
1#左クリックされたカレンダーの年月日を取得する関数(作成中) 2def callback(event): 3 selected_date = '' 4 if event.widget['text'] not in ['Mon','Tue','Wed','Thu','Fri','Sat','Sun']: 5 selected_date += '2020'#ここに表示中の年を代入したい 6 selected_date += '1'#ここに表示中の月を代入したい 7 selected_date += str(event.widget['text']) 8 print(selected_date)
スクリプト全文
以下、上記サイトから引用し手を加えたスクリプト全文です。
python
1# -*- coding:utf-8 -*- 2 3import tkinter as tk 4 5# カレンダーを作成するフレームクラス 6class mycalendar(tk.Frame): 7 def __init__(self,master=None,cnf={},**kw): 8 "初期化メソッド" 9 import datetime 10 tk.Frame.__init__(self,master,cnf,**kw) 11 12 # 現在の日付を取得 13 now = datetime.datetime.now() 14 # 現在の年と月を属性に追加 15 self.year = now.year 16 self.month = now.month 17 18 # frame_top部分の作成 19 frame_top = tk.Frame(self) 20 frame_top.pack(pady=5) 21 self.previous_month = tk.Label(frame_top, text = "<", font = ("",14)) 22 self.previous_month.bind("<1>",self.change_month) 23 self.previous_month.pack(side = "left", padx = 10) 24 self.current_year = tk.Label(frame_top, text = self.year, font = ("",18)) 25 self.current_year.pack(side = "left") 26 self.current_month = tk.Label(frame_top, text = self.month, font = ("",18)) 27 self.current_month.pack(side = "left") 28 self.next_month = tk.Label(frame_top, text = ">", font = ("",14)) 29 self.next_month.bind("<1>",self.change_month) 30 self.next_month.pack(side = "left", padx = 10) 31 32 # frame_week部分の作成 33 frame_week = tk.Frame(self) 34 frame_week.pack() 35 button_mon = d_button(frame_week, text = "Mon") 36 button_mon.grid(column=0,row=0) 37 button_tue = d_button(frame_week, text = "Tue") 38 button_tue.grid(column=1,row=0) 39 button_wed = d_button(frame_week, text = "Wed") 40 button_wed.grid(column=2,row=0) 41 button_thu = d_button(frame_week, text = "Thu") 42 button_thu.grid(column=3,row=0) 43 button_fri = d_button(frame_week, text = "Fri") 44 button_fri.grid(column=4,row=0) 45 button_sta = d_button(frame_week, text = "Sat", fg = "blue") 46 button_sta.grid(column=5,row=0) 47 button_san = d_button(frame_week, text = "Sun", fg = "red")#'San'→'Sun'と修正した 48 button_san.grid(column=6,row=0) 49 50 # frame_calendar部分の作成 51 self.frame_calendar = tk.Frame(self) 52 self.frame_calendar.pack() 53 54 # 日付部分を作成するメソッドの呼び出し 55 self.create_calendar(self.year,self.month) 56 57 def create_calendar(self,year,month): 58 "指定した年(year),月(month)のカレンダーウィジェットを作成する" 59 60 # ボタンがある場合には削除する(初期化) 61 try: 62 for key,item in self.day.items(): 63 item.destroy() 64 except: 65 pass 66 67 # calendarモジュールのインスタンスを作成 68 import calendar 69 cal = calendar.Calendar() 70 # 指定した年月のカレンダーをリストで返す 71 days = cal.monthdayscalendar(year,month) 72 73 # 日付ボタンを格納する変数をdict型で作成 74 self.day = {} 75 # for文を用いて、日付ボタンを生成 76 for i in range(0,42): 77 c = i - (7 * int(i/7)) 78 r = int(i/7) 79 try: 80 # 日付が0でなかったら、ボタン作成 81 if days[r][c] != 0: 82 self.day[i] = d_button(self.frame_calendar,text = days[r][c]) 83 self.day[i].grid(column=c,row=r) 84 except: 85 """ 86 月によっては、i=41まで日付がないため、日付がないiのエラー回避が必要 87 """ 88 break 89 90 def change_month(self,event): 91 # 押されたラベルを判定し、月の計算 92 if event.widget["text"] == "<": 93 self.month -= 1 94 else: 95 self.month += 1 96 # 月が0、13になったときの処理 97 if self.month == 0: 98 self.year -= 1 99 self.month = 12 100 elif self.month == 13: 101 self.year +=1 102 self.month =1 103 # frame_topにある年と月のラベルを変更する 104 self.current_year["text"] = self.year 105 self.current_month["text"] = self.month 106 # 日付部分を作成するメソッドの呼び出し 107 self.create_calendar(self.year,self.month) 108 109# デフォルトのボタンクラス 110class d_button(tk.Button): 111 def __init__(self,master=None,cnf={},**kw): 112 tk.Button.__init__(self,master,cnf,**kw) 113 self.configure(font=("",14),height=2, width=4, relief="flat") 114 self.bind('<Button-1>', callback)#オリジナルに追加した 115 116#左クリックされたカレンダーの年月日を取得する関数(作成中) 117def callback(event): 118 selected_date = '' 119 if event.widget['text'] not in ['Mon','Tue','Wed','Thu','Fri','Sat','Sun']: 120 selected_date += '2020'#ここに表示中の年を代入したい 121 selected_date += '1'#ここに表示中の月を代入したい 122 selected_date += str(event.widget['text']) 123 print(selected_date) 124 125# ルートフレームの定義 126root = tk.Tk() 127root.title("Calendar App") 128mycal = mycalendar(root) 129mycal.pack() 130root.mainloop()
補足
**current_year["text"]とcurrent_month["text"]**が
目的のデータを格納していると思うのですが、
私はクラスに関して初心者のためどう扱ったらよいのかわかりません。
さらに私が新規で書いた関数についても記述する場所はここでよいのか、
それともどちらかのクラスのメソッドとした方がよいのか、よく理解できていません。
その点もアドバイスをいただけると幸いです。
お知恵をお貸しください。よろしくお願いします。

回答3件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2020/03/12 00:08