P
P
PashaLynx2020-10-18 17:42:55
Python
PashaLynx, 2020-10-18 17:42:55

Kivy - how to make checkboxes in the todo app?

Good day to all. I started learning kivy, making a todo application. The question arose - how in the list of cases in each case to have a window where you can put a tick.
main.py code

import os
import ast
import time

from datetime import datetime

from kivy.app import App
from kivy import PY2
from kivy.properties import ObjectProperty
from kivy.uix.screenmanager import Screen
from kivy.config import ConfigParser
from kivy.lang import Builder
from kivy.factory import Factory

if not PY2:
    Builder.load_string(open('ui.kv', encoding='utf-8').read())
else:
    Builder.load_file('ui.kv')


class SortedListFood(Screen):
    def on_enter(self):
        data_foods = self.get_data_foods()
        self.set_list_foods(data_foods)

    def get_data_foods(self):
        return ast.literal_eval(
            App.get_running_app().config.get('General', 'user_data'))

    def set_list_foods(self, data_foods):
        for f, d in sorted(data_foods.items(), key=lambda x: x[1]):
            fd = f.decode('u8') + ' ' + (datetime.fromtimestamp(d).strftime(
                '%Y-%m-%d'))
            data = {'viewclass': 'Button', 'text': fd}
            if data not in self.ids.rv.data:
                self.ids.rv.data.append({'viewclass': 'Button', 'text': fd})


class AddFood(Screen):
    _app = ObjectProperty()

    def set_user_data(self, input_food):
        self._app.user_data = \
            ast.literal_eval(self._app.config.get('General', 'user_data'))
        self._app.user_data[input_food.encode('u8')] = int(time.time())

    def save_user_data(self):
        self._app.config.set('General', 'user_data', self._app.user_data)
        self._app.config.write()

    def set_new_food(self, name_food):
        if not PY2:
            self.ids.result_label.text = \
                "Последнее дело:  " + name_food
        else:
            self.ids.result_label.text = \
                u"Последнее дело:  " + name_food

    def button_clicked(self, input_food):
        self.set_user_data(input_food)
        self.save_user_data()
        self.set_new_food(input_food)


class FoodOptionsApp(App):
    def __init__(self, **kvargs):
        super(FoodOptionsApp, self).__init__(**kvargs)

        self.config = ConfigParser()
        self.screen_manager = Factory.ManagerScreens()
        self.user_data = {}

    def build_config(self, config):
        config.adddefaultsection('General')
        config.setdefault('General', 'user_data', '{}')

    def set_value_from_config(self):
        self.config.read(os.path.join(self.directory, '%(appname)s.ini'))
        self.user_data = ast.literal_eval(self.config.get(
            'General', 'user_data'))

    def get_application_config(self):
        return super(FoodOptionsApp, self).get_application_config(
            '{}/%(appname)s.ini'.format(self.directory))

    def build(self):
        return self.screen_manager


if __name__ == '__main__':
    FoodOptionsApp().run()


code .kv
<[email protected]>:
    MenuScreen:
        id: men

    SortedListFood:
        id: list_todo

    AddFood:
        id: add_todo


<[email protected]>:
    name: "menu"

    canvas:
        Color:
            rgba: 1, 1, 1, 1
        Rectangle:
            pos: self.pos
            size: self.size

    BoxLayout:
        orientation: 'vertical'

        Button:
            text: "Список дел"
            on_release: app.screen_manager.current = 'list_todo'
        Button:
            text: "Добавить дело"
            on_release: app.screen_manager.current = 'add_todo'


<AddFood>:
    name: "add_todo"
    _app: app

    BoxLayout:
        orientation: 'vertical'

        Button:
            text: '< Назад в главное меню'
            on_press: app.screen_manager.current = 'menu'
            size_hint_y: None
            height: dp(40)

        TextInput:
            id: field_food
            multiline: False
            height: dp(40)
            size_hint_y: None
            hint_text: "Дело"

        Button:
            text: "Добавить дело"
            size_hint_y: None
            height: dp(40)
            on_press:
                if field_food.text != '': root.button_clicked(field_food.text); \
                field_food.text = ''

        Label:
            id: result_label


<SortedListFood>:
    name: "list_todo"

    BoxLayout:
        orientation: 'vertical'

        Button:
            text: '< Назад в главное меню'
            on_press: app.screen_manager.current = 'menu'
            size_hint_y: None
            height: dp(40)

        RecycleView:
            id: rv
            key_viewclass: 'viewclass'
            key_size: 'height'

            RecycleBoxLayout:
                default_size: None, dp(40)
                default_size_hint: 1, None
                size_hint_y: None
                height: self.minimum_height
                orientation: 'vertical'


I would also like to know, no one knows whether it is possible to make it so that the case can be dragged to some area on the screen - the trash, and the case would be deleted. Thanks in advance to everyone for your help.

Answer the question

In order to leave comments, you need to log in

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question