前の頁へ   トップ頁へ

老い学の捧げ物 PartⅡ

8.デイトスタンプ

いろいろと試していると、もっとこうしたい、とアイデアが浮かびます。その一つとしてメモを作成した日付を記録したいと思いました。日付はメモ修正の度に更新されますから Labelで表示しようと思います。日付を自動取得してメモ表示画面に表示させましょう。

memo.kv <MemoView>:の追加・修正
 on_memo_content: app.set_memo_content()の引数にself.memo_dateを追加します。
 on_memo_title: app.set_memo_date(self. memo_index)を追加します。
 on_memo_content: app.set_memo_date(self. memo_index)を追加します。
 第2の TextInputの上にdate表示用の Labelを追加するとともに第1の BoxLayoutの背景色を canvasで決めておきます。
 なお配色は適当です。

修正後のmemo.kvです。
< Screen> :
    canvas:
        Color:
            rgb: .2, .2, .2
        Rectangle:
            size: self.size

< MemoView> :
    on_memo_content: app.set_memo_content(self.memo_index, self.memo_date, self.memo_content)
    on_memo_content: app.set_memo_date(self. memo_index)
    on_memo_title: app.set_memo_title(self.memo_index, self.memo_title)
    on_memo_title: app.set_memo_date(self. memo_index)
    BoxLayout:
        orientation: 'vertical'
        canvas:
            Color:
                rgb: .2,.2,.2
            Rectangle:
                pos: self.pos
                size: self.size

        BoxLayout:
            orientation: 'horizontal'
            size_hint_y: None
            height: '48dp'
            padding: '2dp'

            canvas:
                Color:
                    rgb: .2, .2, .2
                Rectangle:
                    pos: self.pos
                    size: self.size

            Button:
                text: 'リスト'
                size_hint_x: None
                width: self.height
                on_release: app.go_memos()
                
            TextInput:
                id: text_box
                text: root.memo_title
                font_size: '16sp'
                multiline: False
                hint_text: 'タイトル'
                on_text: root.memo_title = self.text

            Button:
                text: '消去'
                size_hint_x: None
                width: self.height
                on_release: app.del_memo(root.memo_index)

        Label:
            id: today
            text: root.memo_date
            size_hint_x: None
            size_hint_y: None
            height: '30dp'

        TextInput:
            id: text_box_2
            font_size: '16sp'
            multiline: True
            hint_text: 'メモ内容'
            text: root.memo_content
            on_text: root.memo_content = self.text

< MemoListItem> :
    height: '48sp'
    size_hint_y: None

    canvas:
        Color:
            rgb: .3, .3, .3	
        Rectangle:
            pos: self.pos
            size: self.width, 1

    BoxLayout:
        padding: '5dp'

        Label:
            text: root.memo_title

        Button:
            text: '内容'
            size_hint_x: None
            width: self.height
            on_release: app.edit_memo(root.memo_index)
            
< AllMemoView> :
    BoxLayout:
        orientation: 'vertical'

        BoxLayout:
            orientation: 'horizontal'
            size_hint_y: None
            height: '48dp'
            padding: '5dp'

            canvas:
                Color:
                    rgb: .3, .3, .3		# list表示画面上段の背景色 文字色は白
                Rectangle:
                    pos: self.pos
                    size: self.size

            Image:
                source: 'data/icon.png'
                mipmap: True
                size_hint_x: None
                width: self.height

            Label:
                text: '全メモリスト'
                font_size: '16sp'

            Button:
                text: '追加'
                size_hint_x: None
                width: self.height
                on_release: app.add_memo()

        RecycleView:
            data: root.dataAllMemos
            viewclass: 'MemoListItem'
            RecycleBoxLayout:
                default_size: None, dp(56)
                default_size_hint: 1, None
                size_hint_y: None
                height: self.minimum_height
                orientation: 'vertical'
                spacing: dp(2)

main.pyの追加・修正
 import datetimeを追加
 MemoViewクラスにmemo_date = StringProperty()を追加します。
 AllMemoViewクラスの get_data()メソッドに 'memo_date': item['date'],と追加します。
 MemoAppクラスのadd_memo()メソッドとedit_memo()メソッドを同様に修正します。
 MemoAppクラスのset_memo_content()メソッドの引数にmemo_dateを追加します。
 MemoAppクラスにset_memo_date()メソッドと get_date()メソッドを追加します。
 set_memo_date()メソッドでは、get_date()メソッドで得られた日付データをそのまま使うと JSONDecodeErrorと怒られるので、 str型に変換しています。

修正後のmain.pyです。
import json
from kivy.app import App
from kivy.uix.screenmanager import ScreenManager, Screen, SlideTransition
from kivy.properties import ListProperty, AliasProperty, StringProperty, NumericProperty
from kivy.uix.boxlayout import BoxLayout
import datetime

import urllib.request
from kivy.core.text import LabelBase, DEFAULT_FONT
from kivy.resources import resource_add_path
resource_add_path("font")
LabelBase.register(DEFAULT_FONT, "ipaexg.ttf")

class MemoView(Screen):
    memo_index = NumericProperty()
    memo_title = StringProperty()
    memo_date = StringProperty()
    memo_content = StringProperty()

class MemoListItem(BoxLayout):
    memo_content = StringProperty()
    memo_title = StringProperty()
    memo_index = NumericProperty()
    
class AllMemoView(Screen):
    data = ListProperty()
    def get_data(self):
        return [{
            'memo_index': index,
            'memo_date': item['date'],
            'memo_content': item['content'],
            'memo_title': item['title']}
            for index, item in enumerate(self.data)]
    dataAllMemos = AliasProperty(get_data, bind=['data'])

class MemoApp(App):
    FILENAME="data/memos.json"

    def build(self):
        self.memos = AllMemoView(name='memos')
        self.load_memos()
        self.transition = SlideTransition(duration=.35)
        root = ScreenManager(transition=self.transition)
        root.add_widget(self.memos)
        return root

    def load_memos(self):
        fd = open(self.FILENAME, mode='r')
        data = json.load(fd)
        fd.close()
        self.memos.data = data

    def save_memos(self):
        with open(self.FILENAME, 'w') as fd:
            json.dump(self.memos.data, fd)

    def add_memo(self):
        self.memos.data.append({'title': '', 'date': '', 'content': ''})
        memo_index = len(self.memos.data) - 1
        self.edit_memo(memo_index)

    def edit_memo(self, memo_index):
        memo = self.memos.data[memo_index]
        name = 'memo{}'.format(memo_index)

        if self.root.has_screen(name):
            self.root.remove_widget(self.root.get_screen(name))
        view = MemoView(
            name=name,
            memo_index=memo_index,
            memo_title=memo.get('title'),
            memo_date=memo.get('date'),
            memo_content=memo.get('content'))

        self.root.add_widget(view)
        self.transition.direction = 'left'
        self.root.current = view.name

    def go_memos(self):
        self.transition.direction = 'right'
        self.root.current = 'memos'

    def del_memo(self, memo_index):
        del self.memos.data[memo_index]
        self.save_memos()
        self.refresh_memos()
        self.go_memos()

    def set_memo_title(self, memo_index, memo_title):
        self.memos.data[memo_index]['title'] = memo_title
        self.save_memos()
        self.refresh_memos()

    def set_memo_date(self, memo_index):
        memo_date = str(self.get_date())	# str型に変換しないとJSONDecodeError
        self.memos.data[memo_index]['date'] = memo_date
        self.save_memos()
        self.refresh_memos()

    def set_memo_content(self, memo_index, memo_date, memo_content):
        self.memos.data[memo_index]['content'] = memo_content
        data = self.memos.data
        self.memos.data = []
        self.memos.data = data
        self.save_memos()
        self.refresh_memos()

    def refresh_memos(self):
        data = self.memos.data
        self.memos.data = []
        self.memos.data = data

    def get_date(self):
        return(datetime.date.today())
        
if __name__ == '__main__':
    MemoApp().run()

dataフォルダの memos.jsonファイルに []だけを記述して main.pyを起動しましょう。先ず左端の画像が表示されます。追加ボタンを押すとメモ入力画面に遷移します。日付は空欄ですがメモを入力してリストボタンを押すと、メモ表示画面に遷移して記入したメモのタイトルが表示されています。その内容ボタンを押すとメモ入力画面に遷移し、今度はメモを入力した日付が表示されています。メモ内容を修正すると、日付も修正した日に自動更新され、削除ボタンを押すとそのメモのタイトル、日付、メモ内容のすべてが削除されます。

Ubuntuの環境下、buildozerを使ってこのプログラムからandroidのapkファイルを作成し、スマホにインストールしてみました。アルファベット圏の言語なら問題なく使えますが、日本語でメモを作成しようとしてもスマホのIMEにひらがなが表示されず入力できません。解決法がわからないので、そのままにしています。どなたかお助け下さればありがたいです。
日付スタンプの背景色などお気に召さなければ、memo.kvを修正してお好きな配色に変更してくださいね。TextInputの背景に画像を表示させることもできますが、このシリーズはこれで終了とさせていただきます。Gの拙いコードですが、Python、Kivyを学ぶ方に少しでも参考になれば嬉しいです。

前の頁へ   トップ頁へ