Я написал следующий код с помощью kivymd (python), но мой список не отображается

#python #kivy #kivy-language #kivymd

#python #kivy #kivy-язык #kivymd

Вопрос:

Это мой код (я хочу добавить список на второй экран при нажатии на поиск рецепта …): В моем коде я создал список значков аватара kivy и добавил его на экран, но появляется первый экран, и когда я нажимаю кнопку, он открывает белый экран вместо экрана с надписьюсписок.

MAIN.PY

 import pandas as pd
from kivy.app import App
from kivy.core.window import Window
from kivy.lang import Builder
from kivy.uix.screenmanager import ScreenManager, Screen
from kivymd.app import MDApp
from kivymd.uix.list import OneLineAvatarIconListItem
Builder.load_file('design.kv')
Window.size = (300, 500)
fridge_items = []

class FridgeScreen(Screen):
    tim = []
    def add_item(self):
        global lst
        i = 0
        fridge_items.append(self.ids.inp.text)
        self.ids.inp.text = ''
        for x in range(len(fridge_items)):
            lst = OneLineAvatarIconListItem(text=fridge_items[i])
            i  = 1
        self.ids.list.add_widget(lst)
    def search_recipe(self):
        book = pd.read_csv('RECIPE_BOOK.csv')
        ingredients = book['Ingredients']
        recipe_chodh = book.drop(columns='Recipe')
        lst2 = []
        recipe_freq = {}
        for items in fridge_items:
            for ill in ingredients:
                if items in ill:
                    lst2.append(ill)
        for recipe in lst2:
            if recipe in recipe_freq:
                recipe_freq[recipe]  = 1
            else:
                recipe_freq[recipe] = 1
        top_recipe = sorted(recipe_freq.items(),
                            key=lambda kv: kv[1],
                            reverse=True)
        z = 0
        for items in top_recipe:
            tommy = recipe_chodh[recipe_chodh['Ingredients'] == top_recipe[z][0]].index.values
            foo = recipe_chodh['Name'][int(tommy)]
            self.tim.append(foo)
            z  = 1
        print(self.tim)

class RecipeScreen(Screen):
    def add_lst(self):
        a = 0
        for it in range(len(FridgeScreen.tim)):
            pluto = OneLineAvatarIconListItem(text=FridgeScreen.tim[a])
            root.ids.recipe.add_widget(pluto)
            a  = 1

class My(RecipeScreen):
    def __init__(self, **kwargs):
        super().__init__(**kwargs)
        self.app = App.get_running_app()

class RootScreen(ScreenManager):
    pass

class MainApp(MDApp):
    my = My()
    def build(self):
        return RootScreen()

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

DESIGN.KV

 <FridgeScreen>:
    Screen:
        GridLayout:
            cols: 1
            MDToolbar:
                title: 'KITCHEN'
                left_action_items: [["menu", lambda x : print(x)]]
            GridLayout:
                cols: 1
                padding: 10
                MDTextField:
                    id: inp
                    hint_text: 'enter your ingredients'
                    size_hint_x: None
                    width: 200
                ScrollView:
                    MDList:
                        id: list
            GridLayout:
                cols: 2
                size_hint: 0.2, 0.2
                padding: 10
                spacing: 80
                MDRectangleFlatButton:
                    text: 'search for recipes'
                    on_press: root.search_recipe()
                    on_press: app.my.add_lst()
                    on_press: root.manager.current = 'recipe_screen'
                MDFloatingActionButton:
                    icon: "plus"
                    on_press: root.add_item()
<RecipeScreen>:
    id: recipe_screen
    Screen:
        ScrollView:
            MDList:
                id: recipe
<RootScreen>:
    FridgeScreen:
        name:
            'fridge_screen'
    RecipeScreen:
        name:
            'recipe_screen' 
  

Извините за глупое именование (это юз для развлечения)

Ответ №1:

существует проблема с object <-> class .

Итак, у вас есть класс ‘FridgeScreen’. И экземпляр этого класса, у которого на самом деле нет имени, но он создан в вашем kv-файле:

     FridgeScreen:
        name:
            'fridge_screen'
  

Эта строка:

 self.tim.append(foo)
  

Вы изменяете атрибут вашего экземпляра FridgeScreen.

Эта строка:

 for it in range(len(FridgeScreen.tim)):
  

Вы получаете доступ к атрибуту вашего класса FridgeScreen


И это всего лишь два разных атрибута ;). FirdeScreen.tim всегда является пустым списком, например, инициализированным в строке tim = [] .

Решение:

Дайте вашему экземпляру FridgeScreen имя (= id) и создайте ссылку с вашего RecipeScreen на ваш FridgeScreen:

 <RootScreen>:
    FridgeScreen:
        id: _fridge_screen
        name:
            'fridge_screen'
    RecipeScreen:
        fridge_screen: _fridge_screen
        name:
            'recipe_screen' 
  

Теперь вы можете получить доступ к правильному tim атрибуту в классе RecipeScreen с помощью:

 self.fridge_screen.tim
  

Подсказка: вам нужно будет сделать что-то подобное с root, поскольку по умолчанию root атрибут доступен только в вашем kv-файле.

 RecipeScreen:
    root: root
  

И в вашем коде используйте self.root .