Home > Software engineering >  How to take text value of a kivymd list inside a recycleview?
How to take text value of a kivymd list inside a recycleview?

Time:11-21

I'm new working with kivymd and I need to generate an app with two screens, the second screen shows a TwoLineListItem inside a recycleview, I need to bind a function that takes the text on the selected row a put it in a text field of the main window, but I'm getting this error:

TypeError: click_supplier() missing 1 required positional argument: 'supplier_list_item'

Here's a similar example of my code:

PY

from kivy.lang import Builder
from kivymd.app import MDApp
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.screenmanager import Screen, ScreenManager
from kivymd.uix.list import OneLineListItem, TwoLineListItem
from kivy.uix.recycleview import RecycleView
from kivy.metrics import dp

suppliers=['Amazon', 'Ebay', 'Alibaba', 'Linio', 'Aliexpress']
suppliers_id=['198', '283', '343', '454', '203']


class MainWindow(Screen):
    pass

class SelectSupplierWindow(Screen):
    pass


class BrisaWindowManager(ScreenManager):
    pass


class MainApp(MDApp):

    #define build parameters
    product_dialog=None
    selected_products_list=[]
    def build(self):
        self.theme_cls.theme_style="Light"
        self.theme_cls.primary_palette="Green"
        return Builder.load_file('example.kv')


    def go_to_screen(self, screen):
        self.root.current=screen

    #start suppliers list
    def on_start(self):

        self.set_list_of_suppliers()

    #Autofill supplier search field--------------------------------------------------
    def set_list_of_suppliers(self, text="", search=False):


        def add_supplier_item(name_supplier):
            self.root.get_screen('select_supplier').ids.suppliers_rv.data.append(
                {
                    "viewclass": "TwoLineListItem",
                    "text": name_supplier,
                    "secondary_text": f'Code: {suppliers_id[suppliers.index(name_supplier)]}',
                    "on_release": self.click_supplier,
                }
            )

        self.root.get_screen('select_supplier').ids.suppliers_rv.data = []
        for name_supplier in suppliers:
            if search:
                if text.lower() in name_supplier.lower():
                    add_supplier_item(name_supplier)
            else:
                add_supplier_item(name_supplier)




    def click_supplier(self, supplier_list_item):
        self.root.get_screen('main').ids.oc_supplier.text=supplier_list_item.text
        self.go_to_screen('main')


MainApp().run()

KV

BrisaWindowManager:
    MainWindow:
        id:main_window
    SelectSupplierWindow:

<MainWindow>
    name: 'main'
    MDBoxLayout:
        orientation: 'vertical'
        MDToolbar:
            title: 'Brisa'
        MDBottomNavigation:
            MDBottomNavigationItem:
                id: oc_screen
                name: 'screen 1'
                text: 'Purchase'
                icon: 'clipboard-list'

                MDBoxLayout:
                    orientation: 'vertical'
                    padding:dp(20)
                    spacing: dp(15)

                    MDTextField:
                        id: oc_supplier
                        hint_text: 'Select'
                        helper_text: 'Select'
                        helper_text_mode: 'on_focus'
                        mode: 'fill'
                        halign:'center'
                        on_focus:
                            app.root.current='select_supplier'
                            root.manager.transition.direction='up'

            MDBottomNavigationItem:
                name: 'screen 2'
                text: 'Check'
                icon: 'truck-check'


<SelectSupplierWindow>
    name:'select_supplier'
    MDBoxLayout:
        orientation: 'vertical'
        MDToolbar:
            title: 'Select'
            left_action_items: [['arrow-left', lambda x: app.go_to_screen(screen='main'), 'back']]
        MDBoxLayout:
            orientation:'vertical'
            spacing: dp(10)
            padding: dp(20)
            MDBoxLayout:
                adaptive_height:True

                MDIconButton:
                    icon: 'magnify'
                MDTextField:
                    id: search_field
                    on_text: app.set_list_of_suppliers(self.text, True)
            RecycleView:
                id: suppliers_rv
                key_viewclass: 'viewclass'
                key_size: 'height'
                RecycleBoxLayout:
                    padding: dp(10)
                    default_size: None, dp(60)
                    default_size_hint: 1, None
                    size_hint_y: None
                    height: self.minimum_height
                    orientation: 'vertical'

The error triggered because the click item function needs the clicked row but I haven't been able to bind this event to the function.

Thanks in advance!

CodePudding user response:

How about changing your add_supplier_item() method to:

    def add_supplier_item(name_supplier):
        self.root.get_screen('select_supplier').ids.suppliers_rv.data.append(
            {
                "viewclass": "TwoLineListItem",
                "text": name_supplier,
                "secondary_text": f'Code: {suppliers_id[suppliers.index(name_supplier)]}',
                "on_release": partial(self.click_supplier, name_supplier),
            }
        )

And your click_supplier() method to:

def click_supplier(self, supplier_list_item):
    self.root.get_screen('main').ids.oc_supplier.text=supplier_list_item
    self.go_to_screen('main')

Rather than trying to pass the item, just pass the text.

  • Related