【Pythonista3】カレンダーアプリ開発 Part3

こんにちは、にわこまです!

今回は、Part2で作成したselect_date.pyに追加で関数を作成します。具体的にはカレンダーに日にちを代入する関数やボタンのアクションに紐づけるための関数です。

 

本記事で使用するファイルは以下からダウンロードできます。

 

誤字脱字など何か分からない点がございましたらご連絡お願いいたします!

メールまたはTwitterのDMまで!

 

 

スポンサードサーチ


カレンダーに関連する関数

ここでは2つの関数を作成します。1つは、カレンダーをクリアにする関数です。もう1つは、カレンダーに日にちを代入する関数です。

 

 

コードの提示

カレンダーをクリアにする関数とカレンダーに日にちを代入する関数のソースコードを以下に示します。

from datetime import date
import re
import calendar
import ui


# calendar settings
calendar.setfirstweekday(calendar.SUNDAY)


class SelectDate(ui.View):
    def __init__(self):
        #省略
    def did_load(self):
        self.set_lb_month()
        self.set_calendar_table()
        self.update_table()
        pass
    def set_lb_month(self):
        #省略
    def set_calendar_table(self):
        #省略
    def clear_table(self):
        for sqr in self.sqrs.values():
            sqr.text = ''
        pass
    def update_table(self):
        self.clear_table()
        days = calendar.monthcalendar(
            self.year,
            self.month
        )
        for i, row in enumerate(days):
            for j, day in enumerate(row):
                if(0 < day):
                    k = 'lb_'+str(i)+str(j)
                    self.sqrs[k].text = str(day)
        pass
    pass

 

 

コードの解説

17行目の「self.update_table()」は、カレンダーに日にちを代入する関数を実行しています。select_date.pyuiが読み込まれたときに実行して欲しいため、did_load関数の中に記述しています。

 

 

23行目から26行目の「clear_table関数」は、カレンダーをクリアにする関数です。カレンダーのText属性に空文字列を代入します。

 

24行目の「self.sqrs.values()」は、self.sqrsの値のみのリストです。つまり、カレンダーの日にち部分のラベルオブジェクトのリストです。

 

25行目は、ラベルオブジェクトのText属性に空文字列を代入しています。

 

 

27行目から38行目の「update_table関数」は、カレンダーに日にちを代入する関数です。

 

28行目の「self.clear_table()」は、カレンダーをクリアにしています。

 

29行目の「days」は、今月の日にちが二次元配列で代入される変数です。例えば、2022年12月の日にちは以下のような二次元配列になります。

[[0, 0, 0, 0, 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]]

「0」は日にちがないことを表しています。

「4」や「11」などの1列目は日曜日の日にちになります。8行目に記述した「calendar.setfirstweekday(calendar.SUNDAY)」が効いており、日曜日から日にちが始まるようになっています。

 

33行目と34行目の「for文」は、先の二次元配列を左上から右の順で取得するように繰り返しています。

 

35行目の「if文」は、取得した数値が0より大きいか判断しています。0より大きい場合は、36行目と37行目を実行します。

 

36行目は、日にち部分のラベルのName属性を作成しています。

 

37行目は、self.sqrsの対象のラベルオブジェクトのText属性に取得した数値を文字列に変換して代入しています。

 

 

動作確認

ファイルを保存したら、test_select_date.pyを開きます。右上の「▷」をタップしファイルを実行します。

 

以下のようにカレンダーの日にちが現在の月の日にちを表示していれば動作確認完了です。

 

 

スポンサードサーチ


ボタンに関連する関数

ここでは5つの関数を作成します。

1つ目は、カレンダーのボタンのAction属性に関数を紐づける関数です。

2つ目は、選択された日にちのラベルの背景色とフォント色を変更するための関数です。

3つ目は、ラベルの背景色とフォント色を初期状態に変更するための関数です。

4つ目は、ラベルの背景色とフォント色を選択された状態に変更するための関数です。

5つ目は、選択されたときに実行する関数です。

 

 

コードの提示

ボタンに関連する関数のソースコードを以下に示します。

from datetime import date
import re
import calendar
import ui


# calendar settings
calendar.setfirstweekday(calendar.SUNDAY)


class SelectDate(ui.View):
    def __init__(self):
        #省略
    def did_load(self):
        self.set_lb_month()
        self.set_calendar_table()
        self.update_table()
        self.set_sqr_btn_action()
        pass
    def set_lb_month(self):
        #省略
    def set_calendar_table(self):
        #省略
    def clear_table(self):
        #省略
    def update_table(self):
        #省略
    def set_sqr_btn_action(self):
        for btn in self.btns:
            btn.action = self.tapped_sqr
    def change_state(self):
        self.change_init_state()
        selected_date = self['lb_date'].text
        if(selected_date != self.init_text
        and int(selected_date[5:7])==self.month
        and int(selected_date[0:4])==self.year):
            self.change_selected_state()
    def change_init_state(self):
        self.selected_sqr.bg_color = 'white'
        self.selected_sqr.text_color = 'black'
    def change_selected_state(self):
        self.selected_sqr.bg_color = 'black'
        self.selected_sqr.text_color = 'white'
    def tapped_sqr(self, sender):
        suffix_num = sender.name.split('_')[-1]
        lb_name = 'lb_' + suffix_num
        if(self.sqrs[lb_name].text == ''):
            return
        self.change_init_state()
        self.selected_sqr = self.sqrs[lb_name]
        self.change_selected_state()
        # set tapped date
        tapped_date = self.date_fmt.format(
            self.year,
            self.month,
            int(self.selected_sqr.text)
        )
        self['lb_date'].text = tapped_date
        pass
    pass

 

 

コードの解説

18行目の「self.set_sqr_btn_action()」は、カレンダーのボタンのAction属性に関数を紐づける関数を実行しています。select_date.pyuiが読み込まれたときに実行して欲しいためdid_load関数の中に記述しています。

 

 

28行目から30行目の「set_sqr_btn_action関数」は、カレンダーのボタンのAction属性に関数を紐づける関数です。

 

30行目は、ボタンのAction属性に「self.tapped_sqr関数」を設定しています。つまり、ボタンがタップされたときself.tapped_sqr関数が実行されます。

 

 

31行目から37行目の「change_state関数」は、選択された日にちのラベルの背景色とフォント色を変更する関数です。

 

32行目の「self.change_init_state()」は、ラベルの背景色とフォント色を初期状態に変更するための関数を実行しています。

 

33行目の「selected_date」は、画面最上部のラベルのText属性の値が代入される変数です。

 

34行目から36行目の「if文」は、以下の3つの条件を見たいしているか判断しています。

条件1:初期文字列でないこと。つまり「YYYY/MM/DD」でないこと。

条件2:現在表示している月であること。

条件3:現在表示している年であること。

 

条件1を満たしていない場合は、日にちを選択していないということになります。

 

条件2と条件3を満たしていない場合は、表示している月と年が選択された日付と合致しないということになります。

具体例を示すと、2022/12/01を選択していた場合、2023/12のカレンダーを表示しても1が選択されていない状態になるようになるという事です。

以下の画像は左が2022/12/01を選択した画面で、右が2023/12のカレンダーを表示している画面です。

 
37行目の「self.change_selected_state()」は、ラベルの背景色とフォント色を選択された状態に変更するための関数を実行しています。

 

 

38行目から40行目の「change_init_state関数」は、ラベルの背景色とフォント色を初期状態に変更する関数です。

 

39行目は、選択されたラベルオブジェクトのBackground Color属性を「white」に変更しています。

 

40行目は、選択されたラベルオブジェクトのColor属性を「black」に変更しています。

 

 

41行目から43行目の「change_selected_state関数」は、ラベルの背景色とフォント色を選択された状態に変更する関数です。

 

42行目は、選択されたラベルオブジェクトのBackground Color属性を「black」に変更しています。

43行目は、選択されたラベルオブジェクトのColor属性を「white」に変更しています。

 

 

44行目から59行目の「tapped_sqr関数」は、ボタンがタップされたときに実行する関数です。

 

45行目の「suffix_num」は、タップされたボタンオブジェクトのName属性の数字部分が代入される変数です。

 

46行目の「lb_name」は、タップされたボタンの背面にあるラベルオブジェクトのName属性が代入される変数です。

 

47行目の「if文」は、選択された日にちのラベルオブジェクトのText属性が空文字列であるか判断しています。空文字列である場合は、48行目を実行します。

48行目は、「return」を実行しています。つまり、それ以上処理をせず、関数を終了しています。

 

49行目の「self.change_init_state()」は、ラベルの背景色とフォント色を初期状態に変更するための関数を実行しています。

 

50行目の「self.selected_sqr」は、選択された日にちのラベルオブジェクトが代入される変数です。

51行目の「self.change_selected_state()」は、ラベルの背景色とフォント色を選択された状態に変更するための関数を実行しています。

 

53行目の「tapped_date」は、画面最上部のラベルに表示する日付が代入される変数です。「self.date_fmt」とformat関数を使って日付を作成しています。

 

58行目は、画面最上部のラベルオブジェクトのText属性に選択された日付を代入しています。これにより、選択された日付が表示されます。

 

 

動作確認

ファイルを保存したら、test_select_date.pyを開きます。右上の「▷」をタップしファイルを実行します。

 

以下のように日にちをタップした際に黒く表示されれば動作確認完了です。

 

 

スポンサードサーチ


まとめ

今回は、カレンダー関連の関数とボタン関連の関数を作成しました。状態をクリアにする関数や特定の状態に変更する関数など、少し難しめの関数を作成しました。

 

本記事で作成したファイルは以下からダウンロードできます。

 

次回Part4では日付選択画面に追加で関数を作成します。具体的には、前の月、次の月に移動するためのボタンに関連する関数を作成します。また、アプリの表紙となるUIを作成します。

 

 

最後までお読みいただきありがとうございます。


スポンサードサーチ