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.