Kivy generating 100's of widget

43 views
Skip to first unread message

Klieber frederic

unread,
Jun 25, 2017, 8:52:46 PM6/25/17
to Kivy users support
Hello

I've written an app. wich works file.
My app. displays Movie's cover art thumbnails in a custom widget made with AsyncImage and a Label.
Each Movie corresponds to a widget which is inserted in a stacklayout embded in a scrollview.

If I only insert 50 covers, it's OK, but with 500 it is no more : my Android tablet needs 10 seconds to update all the drawings.

So the question is : is there a better way than that to achieve better performances ?
Can I force the stackLayout to draw while the creation of the widgets is not finished in the for loop ?
I've read something about recycleview, but it seems to be for a list.

Also, the problem is NOT the Loading of the images which takes time after the positionning of the widgets, the problem is a black screen while the widgets arer created and inserted (for loop).

Thank you

ZenCODE

unread,
Jun 26, 2017, 1:54:03 AM6/26/17
to Kivy users support
Rather than a ScollView, use a RecycleView. This is exactly the problem it solves, and avoids you having to generate all of these widgets upfront.

https://kivy.org/docs/api-kivy.uix.recycleview.html

Klieber frederic

unread,
Jun 26, 2017, 7:20:06 AM6/26/17
to Kivy users support
Thanks for your response,ZenCODE.

I've modified my code with your suggestion.
It looks like:

from kivy.app import App
from kivy.lang import Builder
from kivy.uix.recycleview import RecycleView
from kivy.uix.boxlayout import BoxLayout
from pymongo import MongoClient, ASCENDING
from kivy.properties import StringProperty


class WID(BoxLayout):
text = StringProperty()

Builder.load_string('''
<WID>:
AsyncImage:
source: 'to_define'
Label:
text :root.text


<RV>:
viewclass: 'WID'
RecycleBoxLayout:
default_size: None, dp(56)
default_size_hint: 1, None
size_hint_y: None
height: self.minimum_height
orientation: 'vertical'
''')


class RV(RecycleView):
def __init__(self, **kwargs):
super(RV, self).__init__(**kwargs)
client = MongoClient()
db = client.player
mf = db.mediafiles

key = "album"
cursor = mf.find({'$and': [{}, {'album': {'$exists': True}}]}).sort(key, ASCENDING).distinct(key)
self.data = [{'text': str(x)} for x in cursor]


class TestApp(App):
def build(self):
return RV()

if __name__ == '__main__':
TestApp().run()

The display is no more slow but immediate.

BUT it's basically a better ListView and I cannot have a nice arrangement of my widgets with it: one widget is under he other, taking the whole screen width.

So, I suppose I must decide adopting this solution OR leaving my app. as it is (and adding a pagination when the items or too numerous ... )

It seem's that there is no way to have the speed AND the beauty (staskLayout) at the same time.

Best regards

Klieber frederic

unread,
Jun 26, 2017, 7:49:17 AM6/26/17
to kivy-...@googlegroups.com
OK, I've got it ....

I must use a RecycleGridLayout ! Now, evrything works just fine !

Thank you again, ZenCode !
Reply all
Reply to author
Forward
0 new messages