I'm making a kivy app to find the rhyming words for a word entered by the user. It displays all the rhyming words as OneLineListItems
in an MDList
which is inside a kivy RecycleView
. On clicking on one of these OneLineListItems
it displays the definition of the word on the right-hand side of the screen. However, when I click on a OneLineListItem
its definition takes very long to appear and sometimes it lags so badly that the app closes. Am I doing something wrong or is it just my computer? Code below:
from kivymd.app import MDApp
from kivy.lang import Builder
from kivymd.uix.label import MDLabel
from kivymd.uix.list import OneLineListItem
import pronouncing
import enchant
from PyDictionary import PyDictionary
dictionary = PyDictionary()
d = enchant.Dict("en_US")
kv = """
Screen:
input:input
scroll:scroll
word:word
defs:defs
MDGridLayout:
rows: 1
cols: 2
MDGridLayout:
rows: 2
cols: 1
MDFloatLayout:
MDTextField:
id:input
size_hint: (.4, None)
height: 26
multiline: False
on_text_validate: app.rhyme()
hint_text: "Search"
mode: "rectangle"
pos_hint: {"center_x": .25, "center_y": .85}
font_name: "DejaVuSans.ttf"
text_size: self.size
MDFloatLayout:
RecycleView:
size_hint: 0.85,1.5
bar_width: dp(15)
bar_height: dp(40)
scroll_type: ["content"]
pos_hint: {"center_x": 0.45, "center_y": 0.93}
MDList:
id: scroll
MDBoxLayout:
id:defs
orientation: "vertical"
md_bg_color: 0, 1, 0.2, 1
MDLabel:
id: word
text: ""
text_size: self.size
"""
class RhymeApp(MDApp):
played = []
x_turn = True
def build(self):
self.screen = Builder.load_string(kv)
return self.screen
def rhyme(self):
raw_rhymes = pronouncing.rhymes(self.screen.input.text)
rhymes = []
[rhymes.append(x) for x in raw_rhymes if x not in rhymes and x[-1] != "." and d.check(x)]
self.screen.scroll.clear_widgets()
for i in rhymes:
self.screen.scroll.add_widget(
OneLineListItem(text=f"{i}".capitalize(), on_release=self.dictionary)
)
def dictionary(self, btn):
nl = '\n'
self.screen.defs.clear_widgets()
self.screen.word.text = btn.text.capitalize()
meaning = dictionary.meaning(btn.text, disable_errors=True)
if meaning is None:
self.screen.defs.add_widget(
MDLabel(text=f"Sorry, no meaning for that word.",
text_size="self.size")
)
else:
for key in meaning:
self.screen.defs.add_widget(
MDLabel(text=f"Part of speech: {key} {nl}Meaning: {nl}{nl}{meaning[key][0].capitalize()}.",
text_size="self.size")
)
if __name__ == "__main__":
RhymeApp().run()
Can someone please help?
First create a custom class for the data-class like following:
class ListItem(OneLineListItem):
# Here define all the necessary attrs., methods apart from the defaults (if you need any).
Now in your .kv
initialize RecycleView
as,
RecycleView:
id: scroll
#size_hint: 0.85,1.5
bar_width: dp(15)
bar_height: dp(40)
scroll_type: ["content"]
#pos_hint: {"center_x": 0.45, "center_y": 0.93}
viewclass: "ListItem"
RecycleBoxLayout:
default_size: None, dp(48)
default_size_hint: 1, None
size_hint_y: None
height: self.minimum_height
orientation: 'vertical'
Now you are ready to feed RecycleView
with you data as,
def rhyme(self):
...
self.screen.ids.scroll.data = [
{"text" : f"{i}".capitalize()}
for i in rhymes]