Qiwi: can you customize the user interface when adding a large number of widgets?

I have an application that should dynamically add many widgets. Here is a working application to simulate this:

from threading import Thread

from kivy.app import App
from kivy.uix.stacklayout import StackLayout
from kivy.uix.gridlayout import GridLayout
from kivy.uix.label import Label
from kivy.uix.button import Button
from kivy.clock import Clock

class LotsOfWidgets(App):
    def build(self):
        self.widgets_amt = 5000

        root = GridLayout(cols=1)
        self.label_container = StackLayout()

        generate_button = Button(text='Generate lots of labels', 
                              size_hint_y=None, height=44)

        generate_button.bind(on_press=self.generate_lots_of_labels)

        hooray_button = Button(text='Print hooray', 
                               size_hint_y=None, height=44)

        hooray_button.bind(on_press=self.print_hooray)

        for widget in (generate_button, hooray_button, 
                       self.label_container):
            root.add_widget(widget)

        return root

    def generate_lots_of_labels(self, *args):
        for _ in xrange(self.widgets_amt):
            label = Label(text='a', size_hint=(None, None), size=(10,10))
            self.label_container.add_widget(label)

    def scheduled_generate_lots_of_labels(self, *args):
        Clock.schedule_once(self.generate_lots_of_labels)

    def threaded_generate_lots_of_labels(self, *args):
        thread = Thread(target=self.generate_lots_of_labels)
        thread.start()

    def print_hooray(self, *args):
        print 'hooray'

LotsOfWidgets().run()

We have a grid in which there are 2 buttons and a stack layout. By clicking on the first button, 5,000 labels will be generated in the stack layout. The second button only prints "hooray" on the console.

5000 , . , , " ", 3 . , , .

, generate_button.on_press to scheduled_generate_lots_of_labels threaded_generate_lots_of_labels (, ) , , , .

-, , , ?

+4
2

, Kivy Clock.

+3

, . 5000 Clock.schedule_once.

5000 . 1 , 1 , . , .

, Clock.schedule_interval, . build .

def chunk(self, l, n):
    for i in xrange(0, len(l), n):
        yield l[i:i+n]

def generate_lots_of_labels(self, *args):
    n = 500
    interval = 0.01

    self.chunks = list(self.chunk(range(self.widgets_amt), n))
    self.i = 0

    Clock.schedule_interval(self.iterate, interval)

def iterate(self, *args):
    for _ in self.chunks[self.i]:
        label = Label(text='a', size_hint=(None, None), size=(10,10))
        self.label_container.add_widget(label)

    self.i += 1

    if self.i >= len(self.chunks):
        Clock.unschedule(self.iterate)

. n .

0

Source: https://habr.com/ru/post/1538069/


All Articles