Vishak Raj
Vishak Raj

Reputation: 113

KivyMD Hero Item is not working when adding home page

I am using kivyMD Hero items, there i found one issue, the heros are working only if it is in the 1st/main screen,

the code -

from kivy.animation import Animation
from kivy.clock import Clock
from kivy.properties import StringProperty, ObjectProperty
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.gridlayout import GridLayout
from kivy.uix.label import Label
from kivy.uix.screenmanager import ScreenManager, Screen
from kivy.uix.scrollview import ScrollView
from kivymd.app import MDApp
from kivymd.uix.hero import MDHeroFrom, MDHeroTo
from kivymd.uix.imagelist.imagelist import MDSmartTile, MDSmartTileImage, MDSmartTileOverlayContainer
from kivy.metrics import dp
from kivymd.uix.button import MDButton, MDButtonIcon, MDButtonText
from kivymd.uix.screen import MDScreen
from kivymd.uix.screenmanager import MDScreenManager
from kivymd.uix.label.label import MDLabel
from kivymd.uix.scrollview import StretchOverScrollStencil, MDScrollView
from kivymd.uix.gridlayout import MDGridLayout
from kivy.core.window import Window
from functools import partial
import time

class Example2(MDApp):

    def create_tile(self, img_path, index):
        # Create SmartTile
        tag_name = "Tag "+ str(index)
        herofrom = MDHeroFrom(size_hint_y = None, height = "200dp", radius = "24dp",
                            tag=tag_name,
                            )

        tile = MDSmartTile(size_hint=(0.5, None), height="200dp")  # Use size_hint appropriately
        tile.bind(on_release=lambda x: self.switch_to_screen_b(tag=tag_name))

        # Create SmartTileImage
        image = MDSmartTileImage(source=img_path, radius="24dp")
        image.ripple_duration_in_fast = 0.05
        tile.add_widget(image)

        # Create Overlay Container
        overlay = MDSmartTileOverlayContainer(
            md_bg_color=(0, 0, 0, .5),
            adaptive_height=True,
            radius=[0, 0, dp(24), dp(24)],
            padding="8dp",
            spacing="8dp",
        )
        
        label = MDLabel(text=tag_name, theme_text_color='Custom', text_color="white", adaptive_height=True)
        overlay.add_widget(label)
        tile.add_widget(overlay)

        herofrom.add_widget(tile)
        return herofrom

    def switch_to_screen_b(self, tag):
        #time.sleep(0.2)
        print('?tag', tag)
        self.manager.current_heroes = [tag]
        screen_b = self.manager.get_screen("screen B")
        print('screen_b', screen_b)
        print('screen_b.hero_to.tag', self.hero_to.tag)
        self.hero_to.tag = tag
        print('screen_b.hero_to.tag', self.hero_to.tag)
        self.manager.current = "screen B"

    def screenA_fun(self):
        self.screenA = MDScreen(name='screen A')
        scroll_view = MDScrollView()
        grid = MDGridLayout(id='grid', cols=2, spacing="12dp", padding="12dp", adaptive_height = True,)
        for i in range(12):
            hero_item = self.create_tile('4.png', i)
            grid.add_widget(hero_item)

        scroll_view.add_widget(grid)
        self.screenA.add_widget(scroll_view)

    def screenB_fun(self):
        self.hero_to = MDHeroTo(size_hint=(1, None), height="220dp", pos_hint={"top": 1})
        self.screenB = MDScreen(name='screen B', heroes_to=[self.hero_to])
        self.screenB.add_widget(self.hero_to)

        button = MDButton(MDButtonText(text="Move Hero To Screen A"), 
                            pos_hint={"center_x": .5}, y = "36dp")#size_hint_y=None, height=dp(50)
        
        button.bind(on_release=lambda x: self.switch_to_screen_a(self.hero_to))
        self.screenB.add_widget(button)

    def switch_to_screen_a(self, hero_to):
        print('b', hero_to, hero_to.tag)
        self.manager.current = "screen A"
        self.manager.current_heroes = [hero_to.tag]

    def screen0_fun(self):
        self.main = MDScreen(name='screen 0')
        button = MDButton(MDButtonText(text="start"), 
                            pos_hint={"center_x": .5}, y = "36dp")#size_hint_y=None, height=dp(50)
        
        button.bind(on_release=lambda x: self.switch_to_screen_a_1())
        self.main.add_widget(button)

    def switch_to_screen_a_1(self, *args):
        self.manager.current = "screen A"

    def build(self):

        self.theme_cls.theme_style_switch_animation = True
        self.theme_cls.primary_palette = "Orange"
        self.theme_cls.theme_style = "Dark"  # "Light"
        print('self.theme_cls.backgroundColor', self.theme_cls.backgroundColor)
        
        self.manager = MDScreenManager()
        self.manager.primary_palette = "Orange"
        self.manager.theme_style = "Dark"  # "Light"

        self.screen0_fun()
        self.manager.add_widget(self.main)

        self.screenA_fun()
        self.manager.add_widget(self.screenA)

        self.screenB_fun()
        self.manager.add_widget(self.screenB)

        return self.manager

Example2().run()

Here, in this code, in build method, I added this line self.manager.add_widget(self.main) as a main/home page. If i remove this line which means removing the main screen, then the heros are working properly. But when I add this line to add main screen at first, then the heros are not working and showing this error -

kivy_learn_env/lib/python3.10/site-packages/kivymd/uix/transition/transition.py", line 202, in on_complete

hero_from_children = self._hero_from_widget_children[
       KeyError: 'Tag 3'

DEBUG:

in the file kivy_learn_env/lib/python3.10/site-packages/kivymd/uix/transition/transition.py - the function animated_hero_out - class on_complete method - on line 192, = is supposed to call only when the hero item is selected, but instead what happens, it is called when the "screen A" is opened itself

How to solve it, thanks

Upvotes: 0

Views: 32

Answers (0)

Related Questions