当月の足りない日にちを前後の月の日にちで埋めよう
今回は表示するカレンダーの週を6行に固定にして、足りない日にちは前月や翌月の日にちで埋めるようにしてみましょう。
当月以外の日にちは色を灰色にして、当月の日にちとは違いがはっきり分かるようにします。
当月の足りない日にちを前後の月の日にちで埋めるプログラム
足りない日にちを前月と翌月の日にちを使って埋めるため、表示する月の前月と翌月のカレンダーも取得します。
当月、前月、翌月の年と月を取得する処理は、別関数にしてまとめています。
カレンダーを取得するmonthdayscalendar()メソッドは、その月の該当日がない場合は0が返ってくるので、カレンダーの1行目の日にちが0だった場合は前月の最終週の日にちを、カレンダーの5行目以降の日にちが0だった場合は翌月の初週の日にちを割り当てて、色も灰色にしています。
また、イレギュラーな処理として、2026年2月のように2月1日が日曜日で閏年以外の年は週が4行しかないため、5行目と6行目を翌月の日にちを割り当てます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 |
### インポート import datetime import calendar import tkinter ### 定数 WEEK = ["日", "月", "火", "水", "木", "金", "土"] ### 現在年月取得 year = datetime.date.today().year month = datetime.date.today().month ### 関数(カレンダー表示) def func1(arg): ### グローバル変数定義 global year global month ### 月を変更 month += arg ### 表示年月を計算 year,month = func2(year, month) ### ラベルウィジェットを初期化 for widget in frame1.winfo_children(): if isinstance(widget, tkinter.Label): widget.destroy() ### ラベルに年月を設定 label = tkinter.Label(master=frame1, text=str(year) + "年" + str(month) + "月", font=("游ゴシック",20)) ### 年月表示 label.pack() ### カレンダーオブジェクト作成 cl = calendar.Calendar(firstweekday=6) ### 該当年月のカレンダーを取得 cal = cl.monthdayscalendar(year, month) ### ウィジェット初期化 for widget in frame2.winfo_children(): widget.destroy() ### 曜日配列を取得 for i,x in enumerate(WEEK): ### 日曜日は赤、土曜日は青にする if i == 0: label_day = tkinter.Label(master=frame2, text=x, font=("游ゴシック",18), width=3, fg="red") elif i == 6: label_day = tkinter.Label(master=frame2, text=x, font=("游ゴシック",18), width=3, fg="blue") else: label_day = tkinter.Label(master=frame2, text=x, font=("游ゴシック",18), width=3) ### 曜日を表示 label_day.grid(row=0, column=i, pady=2) ### 前月を計算 year_pre,month_pre = func2(year, month-1) ### 前月のカレンダーを取得 cal_pre = cl.monthdayscalendar(year_pre, month_pre) ### 前月の最終週を取得 week_pre = cal_pre[-1] ### 翌月を計算 year_aft,month_aft = func2(year, month+1) ### 翌月のカレンダーを取得 cal_aft = cl.monthdayscalendar(year_aft, month_aft) ### 翌月の初週と2週目を取得 week_aft1 = cal_aft[0] week_aft2 = cal_aft[1] ### 行カウンター row_cnt = 1 ### カレンダー配列を取得 for i,week in enumerate(cal): for j,day in enumerate(week): ### 日曜日は赤、土曜日は青にする if j == 0: color = "red" elif j == 6: color = "blue" else: color = "black" ### 0だったら前月または翌月を設定 if day == 0 and i == 0: day = week_pre[j] color = "gray" elif day == 0 and (i >= 4): day = week_aft1[j] color = "gray" ### 日にちを整形 label_day = tkinter.Label(master=frame2, text="{:>2}".format(day), font=("游ゴシック",18), height=1, fg=color) ### 日にちを表示 label_day.grid(row=row_cnt, column=j, padx=2, pady=2) ### カウントアップ row_cnt = row_cnt + 1 ### 週が4行(2月1日が日曜日で閏年ではない場合) if len(cal) == 4: ### 5行目の色を灰色にして表示 for i,day in enumerate(week_aft1): label_day = tkinter.Label(master=frame2, text="{:>2}".format(day), font=("游ゴシック", 18), height=1, fg="gray") label_day.grid(row=5, column=i, padx=2, pady=2) ### 6行目の色を灰色にして表示 for i,day in enumerate(week_aft2): label_day = tkinter.Label(master=frame2, text="{:>2}".format(day), font=("游ゴシック", 18), height=1, fg="gray") label_day.grid(row=6, column=i, padx=2, pady=2) ### 週が5行 elif len(cal) == 5: ### 最終行を設定 if cal[-1][6] != 0: week_spc = week_aft1 else: week_spc = week_aft2 ### 6行目の色を灰色にして表示 for i,day in enumerate(week_spc): label_day = tkinter.Label(master=frame2, text="{:>2}".format(day), font=("游ゴシック", 18), height=1, fg="gray") label_day.grid(row=6, column=i, padx=2, pady=2) ### 関数(年月調整) def func2(l_year, l_month): ### 月が1未満の場合は前年にする if l_month < 1: l_month = 12 l_year -= 1 ### 月が12より大きい場合は翌年にする elif l_month > 12: l_month = 1 l_year += 1 ### 年と月を返す return l_year,l_month ### メイン画面作成 main = tkinter.Tk() ### 画面サイズ設定 main.geometry("380x380") ### フレーム設定 frame1 = tkinter.Frame(master=main) frame2 = tkinter.Frame(master=main) ### フレーム表示 frame1.pack(pady=20, side="top") frame2.pack() ### ボタン作成 button1 = tkinter.Button(master=frame1, text="<", font=(None,12), command=lambda:func1(-1)) button2 = tkinter.Button(master=frame1, text=">", font=(None,12), command=lambda:func1(1)) ### ボタン表示 button1.pack(side="left") button2.pack(side="left") ### カレンダー表示 func1(0) ### イベントループ main.mainloop() |
カレンダーで表示する週を6行固定にして、足りない日にちは前月や翌月の日にちで埋めています。