From 6a3cfb103ab0ac65ebc05ac582001d74ca0644a3 Mon Sep 17 00:00:00 2001 From: Jan Date: Mon, 13 Mar 2023 22:32:53 +0100 Subject: [PATCH 1/4] Add requirements, implement dialog using KivyMD --- requirements.txt | 11 +++++++ src/main.py | 70 ++++++++++++++++++++++++++++++++++++--------- src/shoppinglist.kv | 34 ++++++++++++++++++---- 3 files changed, 96 insertions(+), 19 deletions(-) create mode 100644 requirements.txt diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..1d0af2d --- /dev/null +++ b/requirements.txt @@ -0,0 +1,11 @@ +certifi==2022.12.7 +charset-normalizer==3.1.0 +docutils==0.19 +idna==3.4 +Kivy==2.1.0 +Kivy-Garden==0.1.5 +kivymd==1.1.1 +Pillow==9.4.0 +Pygments==2.14.0 +requests==2.28.2 +urllib3==1.26.15 diff --git a/src/main.py b/src/main.py index 7f5a552..f6fed4c 100644 --- a/src/main.py +++ b/src/main.py @@ -5,11 +5,16 @@ from kivy.uix.button import Label from kivy.uix.screenmanager import Screen from kivy.config import Config +from kivymd.app import MDApp +from kivymd.uix.button import MDFlatButton +from kivymd.uix.card.card import MDBoxLayout +from kivymd.uix.dialog import MDDialog + Config.set('graphics', 'resizable', '0') Config.set('graphics', 'height', '1000') Config.set('graphics', 'width', '620') -class ShoppingEntry(BoxLayout): +"""class ShoppingEntry(BoxLayout): text = StringProperty() is_checked = BooleanProperty() @@ -37,24 +42,61 @@ class MainScreen(Screen): # load existing shopping entries def on_enter(self): - print("ENTER_MAIN_SCREEN") - - entry = ShoppingEntry() - entry.text = "Test" - entry.is_checked = True - #self.ids["shop"].add_widget(entry) + pass class SettingsScreen(Screen): - pass + pass""" -class MainPage(BoxLayout): - pass +class AddDialog(MDBoxLayout): + def __init__(self, **kwargs): + super().__init__(**kwargs) -class ShoppingListApp(App): - def build(self): - self.title = 'Shopping List App' - return MainPage() + +class ShoppingListApp(MDApp): + add_dialog: MDDialog | None = None + + def build(self): + self.theme_cls.primary_palette = "Teal" + self.theme_cls.theme_style = "Light" + self.title = 'Shopping List App' + + def add_shopping_entry(self): + pass + + def open_add_popup(self): + if self.add_dialog: + return + + # SPRACHE + buttons = [ + MDFlatButton(text='Abbrechen', on_release=self.close_add_popup), + MDFlatButton(text='Bestätigen') + ] + # SPRACHE + self.add_dialog = MDDialog( + title='Eintrag hinzufügen', + type='custom', + content_cls=AddDialog(), + buttons=buttons + ) + + self.add_dialog.open() + + # *args ist noetig, da weitere Parameter mitgegeben werden, die aber nicht genutzt werden + def close_add_popup(self, *args): + if not self.add_dialog: + return + + self.add_dialog.dismiss() + self.add_dialog = None + + def open_new_popup(self): + pass + + def delete_entry(self): + pass + if __name__ == "__main__": app = ShoppingListApp() app.run() diff --git a/src/shoppinglist.kv b/src/shoppinglist.kv index e7d7ef5..453c355 100644 --- a/src/shoppinglist.kv +++ b/src/shoppinglist.kv @@ -79,8 +79,32 @@ app.root.ids.sm.current = 'main' app.root.ids.sm.transition.direction = 'right' -: - ScreenManager: - id: sm - MainScreen: - SettingsScreen +#: +# ScreenManager: +# id: sm +# MainScreen: +# SettingsScreen + +: + size_hint: 1, None + height: '40dp' + orientation: 'vertical' + scpaing: '5dp' + MDTextField: + id: shopping_entry_text + pos_hint: { 'center_y': 0.4 } + # SPRACHE + hint_text: 'Neuer Eintrag' + + +MDFloatLayout: + ScrollView: + size_hint: 0.9, 0.9 + pos_hint: { 'center_y': 0.5, 'center_x': 0.5 } + MDList: + id: shopping_list + MDFloatingActionButton: + icon: 'plus' + elevation_normal: 5 + pos_hint: { 'x': 0.9, 'y': 0.05 } + on_release: app.open_add_popup() From 6156de2fbea67a10369bb086aace4fbff38c7e2d Mon Sep 17 00:00:00 2001 From: Jan Date: Tue, 14 Mar 2023 23:03:39 +0100 Subject: [PATCH 2/4] Add Top(Bottom)AppBar, fix ListItems --- src/main.py | 19 +++++++++++++++---- src/shoppinglist.kv | 40 +++++++++++++++++++++++++++++++--------- 2 files changed, 46 insertions(+), 13 deletions(-) diff --git a/src/main.py b/src/main.py index f6fed4c..24e311f 100644 --- a/src/main.py +++ b/src/main.py @@ -9,6 +9,7 @@ from kivymd.app import MDApp from kivymd.uix.button import MDFlatButton from kivymd.uix.card.card import MDBoxLayout from kivymd.uix.dialog import MDDialog +from kivymd.uix.list import OneLineAvatarIconListItem Config.set('graphics', 'resizable', '0') Config.set('graphics', 'height', '1000') @@ -47,6 +48,16 @@ class MainScreen(Screen): class SettingsScreen(Screen): pass""" +class ShoppingEntry(OneLineAvatarIconListItem): + def __init__(self, text, **kwargs): + super().__init__(**kwargs) + + self.text = text + self.is_checked = False + + def delete(self, shopping_entry): + self.parent.remove_widget(shopping_entry) + class AddDialog(MDBoxLayout): def __init__(self, **kwargs): super().__init__(**kwargs) @@ -54,15 +65,15 @@ class AddDialog(MDBoxLayout): class ShoppingListApp(MDApp): add_dialog: MDDialog | None = None - def build(self): self.theme_cls.primary_palette = "Teal" self.theme_cls.theme_style = "Light" self.title = 'Shopping List App' - def add_shopping_entry(self): - pass + def add_shopping_entry(self, text): + self.root.ids['shopping_list'].add_widget(ShoppingEntry(text=text)) + self.close_add_popup() def open_add_popup(self): if self.add_dialog: @@ -71,7 +82,7 @@ class ShoppingListApp(MDApp): # SPRACHE buttons = [ MDFlatButton(text='Abbrechen', on_release=self.close_add_popup), - MDFlatButton(text='Bestätigen') + MDFlatButton(text='Bestätigen', on_release=lambda args: self.add_shopping_entry("Text")) ] # SPRACHE self.add_dialog = MDDialog( diff --git a/src/shoppinglist.kv b/src/shoppinglist.kv index 453c355..8eb36a4 100644 --- a/src/shoppinglist.kv +++ b/src/shoppinglist.kv @@ -1,11 +1,11 @@ -: - orientation: 'horizontal' - CheckBox: - active: root.is_checked - Label: - text: root.text - Button: - background_normal: 'res/delete.png' +#: +# orientation: 'horizontal' +# CheckBox: +# active: root.is_checked +# Label: +# text: root.text +# Button: +# background_normal: 'res/delete.png' id: float_root # Giving id to button @@ -85,11 +85,25 @@ # MainScreen: # SettingsScreen +: + id: shopping_entry + markup: True + + ImageLeftWidget: + MDCheckbox: + id: shopping_entry_check + # bind to property + + IconRightWidget: + icon: 'res/delete.png' + on_release: root.delete(shopping_entry) + : size_hint: 1, None height: '40dp' orientation: 'vertical' - scpaing: '5dp' + spacing: '5dp' + MDTextField: id: shopping_entry_text pos_hint: { 'center_y': 0.4 } @@ -98,11 +112,19 @@ MDFloatLayout: + + MDTopAppBar: + #SPRACHE + title: 'Shopping-List-App' + md_bg_color: app.theme_cls.accent_color + right_action_items: [['res/settings.png', lambda x: app.navigate_to_settings()]] + ScrollView: size_hint: 0.9, 0.9 pos_hint: { 'center_y': 0.5, 'center_x': 0.5 } MDList: id: shopping_list + MDFloatingActionButton: icon: 'plus' elevation_normal: 5 From 15158232cb25816ff9a3e390c7c08dbd10d95234 Mon Sep 17 00:00:00 2001 From: Jan Date: Thu, 16 Mar 2023 20:11:43 +0100 Subject: [PATCH 3/4] Remove old classes and kv definitions, add navigation, first version of settings page, general theming --- src/main.py | 77 +++++++----------- src/shoppinglist.kv | 193 +++++++++++++++++++++----------------------- 2 files changed, 120 insertions(+), 150 deletions(-) diff --git a/src/main.py b/src/main.py index 24e311f..37fbd06 100644 --- a/src/main.py +++ b/src/main.py @@ -1,8 +1,9 @@ +from os import name from kivy.app import App from kivy.properties import ListProperty, StringProperty, BooleanProperty, ObjectProperty from kivy.uix.boxlayout import BoxLayout from kivy.uix.button import Label -from kivy.uix.screenmanager import Screen +from kivy.uix.screenmanager import Screen, ScreenManager from kivy.config import Config from kivymd.app import MDApp @@ -15,39 +16,6 @@ Config.set('graphics', 'resizable', '0') Config.set('graphics', 'height', '1000') Config.set('graphics', 'width', '620') -"""class ShoppingEntry(BoxLayout): - text = StringProperty() - is_checked = BooleanProperty() - - def __init__(self, **kwargs): - super(ShoppingEntry, self).__init__(**kwargs) - -class MainScreen(Screen): - shoppingEntries = ListProperty([]) - shop = ObjectProperty(BoxLayout()) - - def __init__(self, *args, **kwargs): - super(MainScreen, self).__init__(*args, **kwargs) - self.add_shopping_entry("Test", True) - - def add_shopping_entry(self, text: str, is_checked: bool): - entry = ShoppingEntry() - entry.text = text - entry.is_checked = is_checked - - self.shop.add_widget(entry) - self.shop.add_widget(Label(text="Hallo")) - print("ADD_ENTRY") - - self.shoppingEntries.append(entry) - - # load existing shopping entries - def on_enter(self): - pass - -class SettingsScreen(Screen): - pass""" - class ShoppingEntry(OneLineAvatarIconListItem): def __init__(self, text, **kwargs): super().__init__(**kwargs) @@ -62,19 +30,9 @@ class AddDialog(MDBoxLayout): def __init__(self, **kwargs): super().__init__(**kwargs) - -class ShoppingListApp(MDApp): +class ShoppingEntryScreen(Screen): add_dialog: MDDialog | None = None - def build(self): - self.theme_cls.primary_palette = "Teal" - self.theme_cls.theme_style = "Light" - self.title = 'Shopping List App' - - def add_shopping_entry(self, text): - self.root.ids['shopping_list'].add_widget(ShoppingEntry(text=text)) - self.close_add_popup() - def open_add_popup(self): if self.add_dialog: return @@ -102,12 +60,35 @@ class ShoppingListApp(MDApp): self.add_dialog.dismiss() self.add_dialog = None - def open_new_popup(self): - pass + + def add_shopping_entry(self, text): + self.ids['shopping_list'].add_widget(ShoppingEntry(text=text)) + self.close_add_popup() def delete_entry(self): pass - + + def navigate_to_settings(self): + self.manager.transition.direction = 'left' + self.manager.current = 'settings' + +class SettingsScreen(Screen): + def navigate_to_shopping_list(self): + self.manager.transition.direction = 'right' + self.manager.current = 'shopping' + +class ShoppingListApp(MDApp): + def build(self): + self.theme_cls.primary_palette = "Teal" + self.theme_cls.theme_style = "Light" + self.title = 'Shopping List App' + + sm = ScreenManager() + sm.add_widget(ShoppingEntryScreen(name='shopping')) + sm.add_widget(SettingsScreen(name='settings')) + + return sm + if __name__ == "__main__": app = ShoppingListApp() app.run() diff --git a/src/shoppinglist.kv b/src/shoppinglist.kv index 8eb36a4..3925f03 100644 --- a/src/shoppinglist.kv +++ b/src/shoppinglist.kv @@ -1,90 +1,3 @@ -#: -# orientation: 'horizontal' -# CheckBox: -# active: root.is_checked -# Label: -# text: root.text -# Button: -# background_normal: 'res/delete.png' - - - id: float_root # Giving id to button - size_hint: (None, None) - text: '' - btn_size: (70, 70) - size: (70, 70) - bg_color: (0.404, 0.227, 0.718, 1.0) - - # Adding shape and all, size, position to button - Button: - text: float_root.text - markup: True - font_size: 40 - size_hint: (None, None) - size: float_root.btn_size - pos_hint: {'right': 8.5, 'top': 1.25} - background_normal: '' - background_color: (0, 0, 0, 0) - canvas.before: - Color: - rgba: (0.3, 0.5, 0.2, 1.0) - Ellipse: - size: self.size - pos: self.pos - -: - shop: shop - - name: 'main' - MainTitleBar: - BoxLayout: - id: shop - orientation: 'vertical' - FloatButton: - text: '+' - markup: True - background_color: 1, 0, 1, 0 - -: - name: 'settings' - SettingsTitleBar: - Label: - text: 'hi settings' - - -: - pos_hint: {'top':1} - ActionView: - ActionPrevious: - title: 'Shopping Liste' - app_icon: 'res/shopping_bag.png' - with_previous: False - ActionButton: - text: 'Sort' - icon: 'res/filter_list.png' - ActionButton: - text: 'Settings' - icon: 'res/settings.png' - on_release: - app.root.ids.sm.current = 'settings' - app.root.ids.sm.transition.direction = 'left' - -: - pos_hint: {'top':1} - ActionView: - ActionPrevious: - title: 'Einstellungen' - app_icon: 'res/settings.png' - on_release: - app.root.ids.sm.current = 'main' - app.root.ids.sm.transition.direction = 'right' - -#: -# ScreenManager: -# id: sm -# MainScreen: -# SettingsScreen - : id: shopping_entry markup: True @@ -109,24 +22,100 @@ pos_hint: { 'center_y': 0.4 } # SPRACHE hint_text: 'Neuer Eintrag' - + +: + MDBoxLayout: + orientation: 'vertical' + pos_hint: { 'center_x': 0.5, 'center_y': 0.5 } -MDFloatLayout: + MDTopAppBar: + #SPRACHE + title: 'Shopping-List-App' + md_bg_color: app.theme_cls.primary_color + specific_text_color: '#000000' + right_action_items: [['res/settings.png', lambda x: root.navigate_to_settings()]] - MDTopAppBar: - #SPRACHE - title: 'Shopping-List-App' - md_bg_color: app.theme_cls.accent_color - right_action_items: [['res/settings.png', lambda x: app.navigate_to_settings()]] - - ScrollView: - size_hint: 0.9, 0.9 - pos_hint: { 'center_y': 0.5, 'center_x': 0.5 } - MDList: - id: shopping_list + ScrollView: + size_hint: 0.85, 0.85 + pos_hint: { 'center_y': 1, 'center_x': 0.5 } + MDList: + id: shopping_list MDFloatingActionButton: icon: 'plus' elevation_normal: 5 - pos_hint: { 'x': 0.9, 'y': 0.05 } - on_release: app.open_add_popup() + pos_hint: { 'center_x': 0.925, 'center_y': 0.05 } + on_release: root.open_add_popup() + +: + MDBoxLayout: + orientation: 'vertical' + + MDTopAppBar: + #SPRACHE + title: 'Shopping-List-App' + md_bg_color: app.theme_cls.primary_color + specific_text_color: '#000000' + left_action_items: [['res/arrow_back.png', lambda x: root.navigate_to_shopping_list()]] + + MDBoxLayout: + orientation: 'horizontal' + pos_hint: { 'center_x': 0.5 } + size_hint: (0.5, 0.25) + # SPRACHE + MDLabel: + text: 'Sprache' + MDDropDownItem: + id: language_drop_down + text: 'Deutsch' + + MDBoxLayout: + orientation: 'horizontal' + pos_hint: { 'center_x': 0.5 } + size_hint: (0.5, 0.25) + # SPRACHE + MDLabel: + text: 'Theme' + MDSwitch: + width: dp(36) + + MDBoxLayout: + orientation: 'horizontal' + pos_hint: { 'center_x': 0.5 } + size_hint: (0.5, 0.25) + # SPRACHE + MDLabel: + text: 'MQTT-Server' + MDTextField: + hint_text: 'mqtt.server.de' + + MDBoxLayout: + orientation: 'horizontal' + pos_hint: { 'center_x': 0.5 } + size_hint: (0.5, 0.25) + # SPRACHE + MDLabel: + text: 'MQTT-Topic' + MDTextField: + hint_text: 'topic' + + MDBoxLayout: + orientation: 'horizontal' + pos_hint: { 'center_x': 0.5 } + size_hint: (0.5, 0.25) + # SPRACHE + MDLabel: + text: 'MQTT-Benutzername' + MDTextField: + hint_text: 'username' + + MDBoxLayout: + orientation: 'horizontal' + pos_hint: { 'center_x': 0.5 } + size_hint: (0.5, 0.25) + # SPRACHE + MDLabel: + text: 'MQTT-Passwort' + MDTextField: + password: True + From ea487e70899c75e0d253ed2a3926144879ba5abd Mon Sep 17 00:00:00 2001 From: Jan Date: Thu, 16 Mar 2023 22:15:26 +0100 Subject: [PATCH 4/4] Add .buildozer directory to gitignore --- .gitignore | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.gitignore b/.gitignore index b6e4761..6034e6b 100644 --- a/.gitignore +++ b/.gitignore @@ -127,3 +127,6 @@ dmypy.json # Pyre type checker .pyre/ + +# Kivy +.buildozer/