python kivy приложение перестает функционировать после добавления виджета (на ПК)
Поудалял все лишнее, оставив только необходимое для воспроизведения такого же поведения.
Есть MDTextField в котором при вводе текста , если есть совпадения появляется MDDropdownMenu с вариантами выбора. Варианты хранятся в списке P_LIST. Если не вводить текст в этот MDTextField, все функционирует. Как только вводишь текст, срабатывает функция, появляется меню, выбираешь. После этого приложение не функционирует.
Определил что происходит это из-за строчки:
self.add_widget(listdropdown) # <----------- пометил в коде
Меню появляется и без add_widget, но если вводить не одну букву, а больше, каждый раз создается новый экземпляр класса ListDropdownValue и меню накладываются друг на друга.
#kivymd 0.104.2
#kivy 2.0.0
from kivy.clock import Clock
from kivy.lang import Builder
from kivy.metrics import dp
from kivy.properties import ObjectProperty
from kivymd.app import MDApp
from kivy.uix.boxlayout import BoxLayout
from kivymd.uix.menu import MDDropdownMenu
kv_str = """
<StartScreen>:
startscreen_textfield_1: textfield_id
BoxLayout:
orientation: "vertical"
BoxLayout:
size_hint: 1, 0.5
BoxLayout:
size_hint: 1, 0.5
orientation: "vertical"
BoxLayout:
MDTextField:
id: textfield_id
on_text:
root.open_listdropdown(textfield_id)#
BoxLayout:
MDTextField:
BoxLayout:
MDTextField:
"""
P_LIST = ["ASD", "SDF", "AASD"]
def search_product(prefix):
filtered_list = []
filtered_list = list(filter(lambda l: l.startswith(prefix), P_LIST))
return filtered_list
class MyListDropdownValue(MDDropdownMenu):
def __init__(self, dropdown_list, **kwargs):
super().__init__(**kwargs)
self.dropdown_list_id = dropdown_list
def list_dropdown(self):
if len(self.dropdown_list_id.text) != 0:
prefix = self.dropdown_list_id.text.upper()
filtered_list = search_product(prefix)
menu_items = [{'text':f'{value}',
"height": dp(56),
"viewclass": "OneLineListItem",
"on_release": lambda x= f"{value}": self.set_item(x)}
for value in filtered_list]
self.menu = MDDropdownMenu(
caller=self.dropdown_list_id,
items=menu_items,
width_mult=5,
)
self.menu.open()
def set_item(self, value):
def set_item(interval):
self.dropdown_list_id.text = value
self.menu.dismiss()
Clock.schedule_once(set_item, 0.1)
class StartScreen(BoxLayout):
startscreen_textfield_1 = ObjectProperty()
def open_listdropdown(self, id):
if len(self.children) > 1:
self.children[0].dismiss()
self.remove_widget(self.children[0])
listdropdown = MyListDropdownValue(id)
self.add_widget(listdropdown) # <--------------
listdropdown.list_dropdown()
kv = Builder.load_string(kv_str)
class Program(MDApp):
def build(self):
self.screen = StartScreen()
return self.screen
def main():
app = Program()
app.run()
if __name__ == "__main__":
main()