kivymd / KivyMD

KivyMD is a collection of Material Design compliant widgets for use with Kivy, a framework for cross-platform, touch-enabled graphical applications. https://youtube.com/c/KivyMD https://twitter.com/KivyMD https://habr.com/ru/users/kivymd https://stackoverflow.com/tags/kivymd
https://kivymd.readthedocs.io
MIT License
2.21k stars 665 forks source link

dynamic color example not working #1727

Open Epierre31 opened 1 month ago

Epierre31 commented 1 month ago

context: kivy 2.3 kivyMD 2.0.1dev0 python 3.11 desktop : Windows 10

chapter 'dynamic_color' when trying to run the example:"Example of dynamic color from the list of standard color schemes", not color scheme change when selectting various color from "set palette menu"

after numerous tests, it seems that

1) I don't know if this is the expected behavior dynamic_color = True ==> change only through path_to_wallpaper (2nd example) dynamic_color = False ==> change only through assigning new primary_palette 2) fact is : First example is not working on my desktop

correct code (with some comments)

from kivy.clock import Clock from kivy.lang import Builder from kivy.properties import StringProperty, ColorProperty from kivy.uix.boxlayout import BoxLayout from kivy.utils import hex_colormap from kivymd.dynamic_color import DynamicColor

from kivymd.uix.menu import MDDropdownMenu from kivymd.app import MDApp

KV = '''

orientation: "vertical" MDLabel: text: root.text color: "grey" adaptive_height: True MDCard: theme_bg_color: "Custom" md_bg_color: root.bg_color MDScreen: md_bg_color: app.theme_cls.backgroundColor MDIconButton: on_release: app.open_menu(self) pos_hint: {"top": .98} x: "12dp" icon: "menu" MDRecycleView: id: card_list viewclass: "ColorCard" bar_width: 0 size_hint_y: None height: root.height - dp(68) RecycleGridLayout: cols: 3 spacing: "16dp" padding: "16dp" default_size: None, dp(56) default_size_hint: 1, None size_hint_y: None height: self.minimum_height ''' class ColorCard(BoxLayout): text = StringProperty() bg_color = ColorProperty() class Example(MDApp): menu: MDDropdownMenu = None def build(self): # if dynamic_color = True, the color scheme may be changed but while using the path_to_wallpaper only # if dynamic_color = True, the color scheme may be changed by assigning primary_palette with a new color name self.theme_cls.dynamic_color = False self.theme_cls.theme_style = "Dark" return Builder.load_string(KV) def get_instance_from_menu(self, name_item): index = 0 rv = self.menu.ids.md_menu opts = rv.layout_manager.view_opts datas = rv.data[0] for data in rv.data: if data["text"] == name_item: index = rv.data.index(data) break instance = rv.view_adapter.get_view( index, datas, opts[index]["viewclass"] ) return instance def open_menu(self, menu_button): menu_items = [] for item, method in { "Set palette": lambda: self.set_palette(), "Switch theme style": lambda: self.theme_switch(), }.items(): menu_items.append({"text": item, "on_release": method}) self.menu = MDDropdownMenu( caller=menu_button, items=menu_items, ) self.menu.open() def set_palette(self): instance_from_menu = self.get_instance_from_menu("Set palette") available_palettes = [ name_color.capitalize() for name_color in hex_colormap.keys() ] menu_items = [] for name_palette in available_palettes: menu_items.append( { "text": name_palette, "on_release": lambda x=name_palette: self.switch_palette(x), } ) MDDropdownMenu( caller=instance_from_menu, items=menu_items, ).open() def switch_palette(self, selected_palette): self.theme_cls.primary_palette = selected_palette Clock.schedule_once(self.generate_cards, 0.5) def theme_switch(self) -> None: self.theme_cls.switch_theme() Clock.schedule_once(self.generate_cards, 0.5) def generate_cards(self, *args): self.root.ids.card_list.data = [] __schemes_name_colors = [] for property_name in dir(DynamicColor): if '_' not in property_name: __schemes_name_colors.append(property_name) for color in __schemes_name_colors: value = color self.root.ids.card_list.data.append( { "bg_color": getattr(self.theme_cls, value), "text": value, } ) # print(f"bg_color: {getattr(self.theme_cls, value)} value {value}") # print (f"generation of card with palette {self.theme_cls.primary_palette}") def on_start(self): Clock.schedule_once(self.generate_cards) Example().run()