ForyszeP
ForyszeP

Reputation: 163

How to stimulate button in kivy?

How to make press method on this code working? When I press a button the list populates, but when I call it from Clock then not. I can see populate print on the console but the list does not appear in the view. I mean simply: how to stimulate pressing the button in the code?

from kivy.config import Config
Config.set('graphics', 'multisamples', '0')
from random import sample
from string import ascii_lowercase
import pyrebase
from kivy.app import App
from kivy.lang import Builder
from kivy.uix.boxlayout import BoxLayout
from kivy.clock import Clock

kv = """

<Row@BoxLayout>:

    canvas.before:
        Color:
            rgba: 0.5, 0.5, 0.5, 1
        Rectangle:
            size: self.size
            pos: self.pos
    value: ''
    Label:
        text: root.value

<Test>:
    canvas:
        Color:
            rgba: 0.3, 0.3, 0.3, 1
        Rectangle:
            size: self.size
            pos: self.pos
    rv: rv
    orientation: 'vertical'
    GridLayout:
        cols: 3
        rows: 2
        size_hint_y: None
        height: dp(108)
        padding: dp(8)
        spacing: dp(16)
        Button:
            id: populate_btn
            text: 'Populate list'
            on_press: root.populate()



    RecycleView:
        id: rv
        scroll_type: ['bars', 'content']
        scroll_wheel_distance: dp(114)
        bar_width: dp(10)
        viewclass: 'Row'
        RecycleBoxLayout:
            default_size: None, dp(56)
            default_size_hint: 1, None
            size_hint_y: None
            height: self.minimum_height
            orientation: 'vertical'
            spacing: dp(2)
"""

Builder.load_string(kv)


class Test(BoxLayout):


    def __init__(self, **kwargs):
        super().__init__(**kwargs)

    def populate(self):
        print("populate")

        self.rv.data = [{'value': ''.join(sample(ascii_lowercase, 6))}
                        for x in range(50)]

    def press(self):
        self.ids.populate_btn.dispatch('on_press')


def interval(dt):
    x = Test()
    x.press()

Clock.schedule_interval(interval, 3)


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

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

Upvotes: 1

Views: 54

Answers (1)

eyllanesc
eyllanesc

Reputation: 243897

The error is caused because the Test object created in interval function is different from the Test object that returns build method, besides that the Test object created in interval is eliminated since it is a local variable. So the solution is to use the same reference by passing it to the interval function for it I will use functools.partial() function.

# ...
from functools import partial

# ...

def interval(x, dt):
    x.press()

class TestApp(App):
    def build(self):
        t = Test()
        Clock.schedule_interval(partial(interval, t), 3)
        return t
# ...

Upvotes: 1

Related Questions