Forum Archive

Understanding UI redraw / animation

spinmaster

Hi All.

I'm loving the new 2.0 update.

I'm trying to get my head around how the UI module handles redraws / screen updates.

I'm trying to do a simple test where a series of labels blink in series (kind of like a row of LEDs, but text labels instead). I've found the UI.animate and UI.delay functions . However, I get an error when placing UI.delay in a loop.

It's calls the function correctly the first call, but on subsequent it gives me error of "Type Error: Expected Callable Function"

Here is code...can anyone illuminate problem?

import ui

def colorIt(lbl):
    lbl.background_color='#ff0000'

def buttonClick(sender):
    for item in llst:
        print item
        ui.delay(colorIt(item),1.0)

v = ui.load_view()

lbl1=v['label1']
lbl2=v['label2']
lbl3=v['label3']
llst=[lbl1,lbl2,lbl3]

v.present('sheet')
omz

ui.delay expects a callable object, typically a function, but you're passing the result of a function call (which is None in this case because colorIt doesn't return anything).

The function that you pass to ui.delay() must not take any parameters. To get the result you're looking for, you can use functools.partial() to transform a function with arguments (colorIt()) into one without.

This should work (untested):

import ui
from functools import partial

def colorIt(lbl):
    lbl.background_color='#ff0000'

def buttonClick(sender):
    for i, item in enumerate(llst):
        print item
        ui.delay(partial(colorIt, item), 1.0 * (i+1))

v = ui.load_view()

lbl1=v['label1']
lbl2=v['label2']
lbl3=v['label3']
llst=[lbl1,lbl2,lbl3]

v.present('sheet')
spinmaster

@omz said:

ui.delay expects a callable object, typically a function, but you're passing the result of a function call (which is None in this case because colorIt doesn't return anything).

Many thanks OMZ. I understand.

I suppose to other approach is to refactor the code so that the called function has no parameters - but for this simple example partial seems easier.