2

When an "OK button" is clicking, my kivy app retrieves a list of sometimes 100+ folders and displays a GridLayout with 4 columns and 1 row per folder. Each row has 3 scrollable labels and 1 checkbox. This GridLayout sometimes takes close to 12 sec to be generated so I would like to display something (a label, an image...) in the meantime.

Attempt 1: My "Ok button" calls a def DisplayTable. I tried to simply add self.add_widget(Label_when_waiting) right at the beginning of DisplayTable (so before any processing or generating the GridLayout) but the Label_when_waiting is displayed only when GridLayout is displayed.

Attempt 2: I tried to separate def DisplayTable into two def, Diplay_Label_when_waiting(the one called by the "OK button") and DisplayTable:

def Diplay_Label_when_waiting(self, *args):
    self.add_widget(Label_when_waiting)
    DisplayTable(self, *args)

But here again, Label_when_waiting is displayed only when GridLayout is displayed.

So how can I display Label_when_waiting before GridLayout knowing that both displays have to be triggered by the "Ok button"

MagTun
  • 5,619
  • 5
  • 63
  • 104

1 Answers1

4

Use Clock.schedule_once to display the Grid after the label is shown:

def Diplay_Label_when_waiting(self, *args):
    self.add_widget(Label_when_waiting)
    Clock.schedule_once(lambda dt: DisplayTable(self, *args), 0)

You can also use delayable from kivyoav (DISCLAIMER - I'm the author ...)

from kivyoav.delayed import delayable

@delayable
def Diplay_Label_when_waiting(self, *args):
    self.add_widget(Label_when_waiting)
    yield 0.0 # delay of 0ms , will cause the UI to update...
    DisplayTable(self, *args)
Yoav Glazner
  • 7,936
  • 1
  • 19
  • 36
  • Thanks a lot this is working. Thanks for the module, I will try it tomorrow I don’t understand why it works with a clock and not when I call the definition directly. Why should I use a clock? – MagTun Mar 15 '17 at 19:39
  • 1
    To let the kivy event loop time to update the screen – Yoav Glazner Mar 16 '17 at 07:05
  • Thanks Yoav for your answer. I am still confused, if it's only to give time to update the screen, why `time.sleep` isn't working (this code doesn't display the label: `self.add_widget(Label_when_waiting) time.sleep(5) self.DisplayTable(self)` ) – MagTun Mar 16 '17 at 14:46
  • 1
    Because the **main event loop thread** is stuck on the **sleep call** - In other words the event loop is waiting for your function to end, It doesn't matter if you *sleep* or do *real work*, if the function doesn't return the event loop is stuck. – Yoav Glazner Mar 19 '17 at 11:25