I'm trying to design a user interface in Python / Kivy MD. Starting from an example, I developed an interface with a simple drop down widget, such as a combobox. When the app runs, the widget should display its elements. Here is the code:
from kivy.lang import Builder
from kivy.metrics import dp
from kivy.properties import StringProperty
from kivymd.uix.list import OneLineIconListItem
from kivymd.app import MDApp
from kivymd.uix.menu import MDDropdownMenu
KV = '''
#:import toast kivymd.toast.toast
MDScreen
MDDropDownItem:
id: drop_item
pos_hint: {'center_x': .5, 'center_y': .5}
text: 'FREQUENCY'
on_release: app.menu.open()
select: toast(self.current_item)
'''
class MainApp(MDApp):
def __init__(self, **kwargs):
super().__init__(**kwargs)
self.screen = Builder.load_string(KV)
myItems = ['300 Hz', '200 Hz', '100 Hz']
menu_items = self.create_combobox_items(self.screen.ids.drop_item, myItems)
# WAY 1: WORKS --- COMMENT THIS BLOCK
########################################
self.menu = MDDropdownMenu(
caller = self.screen.ids.drop_item,
items = menu_items,
position = "bottom", #top, bottom, center, auto
width_mult = 2,
)
########################################
# WAY 2: DOESN'T WORK --- UNCOMMENT ONLY THE FOLLOWING LINE
########################################
self.menu = self.create_dropdown_object(self.screen.ids.drop_item, menu_items, 'auto', 2)
########################################
self.menu.bind()
def create_dropdown_object(dropDownItem, menuItems, pos, width):
ddMenu = MDDropdownMenu(
caller = dropDownItem,
items = menuItems,
position = pos, #top, bottom, center, auto
width_mult = width,
)
return ddMenu
def create_combobox_items(self, dropDownItem, itemList):
comboBoxItems = [
{
"viewclass": "OneLineListItem",
"text": itemList[i],
"height": dp(56),
"on_release": lambda x = itemList[i]: self.set_item(dropDownItem, self.menu, x),
} for i in range(len(itemList))
]
return comboBoxItems
def set_item(self, dropDownItem, dropDownMenu, textItem):
dropDownItem.set_item(textItem)
dropDownMenu.dismiss()
def build(self):
return self.screen
if __name__ == '__main__':
MainApp().run()
This code (WAY 1) works fine. I'm trying to develop a method for the MDDropDownItem widget creation, namely create_dropdown_object. When I comment the way 1 code block, and use the method defined below (WAY 2), I get the TypeError: create_dropdown_object() takes 4 positional arguments but 5 were given. How it can be possible considering that I passed 4 arguments to the function?
Inside the class function self keyword need to be in parameter.
You Forgot to mention self inside the class function. Add self will fix the issue
def create_dropdown_object(self, dropDownItem, menuItems, pos, width):
ddMenu = MDDropdownMenu(
caller = dropDownItem,
items = menuItems,
position = pos, #top, bottom, center, auto
width_mult = width,
)
return ddMenu
Above change will fix your issue