Events and Callbacks

In this page you will find general idea and syntex for adding callbacks. This is applicable for all UI types.

Simply speaking, events are things like mouse click (onClick), mouse entering or exiting UI, some keyboard key getting pressed etc.

Callback or callback function, is the function, you can pass to the UI (Button, TextFields etc) as parameter, for any particular event. When that event occurs that function will be called.

Callbacks for all UI types are described in their respective pages. This page only explains the way parameters(functions) need to be passed.

In boss you can add callbacks using two ways:

  1. When creating UI, there will be a way to add callback as a parameter. For Button, there is a ButtonData class, which is a separate class because Button has so many events.

  2. Every UI class, for every event, also defines, corresponding method to add callback, that can be used after the UI object is created.

Example will make it more clear, I will take example of Button’s onClick event, but it’s applicable for all event types (eg onTextChange of TextField):

Below is the code which is followed by explanation:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
from boss.ui_creator import UICreator, Boss_OT_base_ui, ButtonData, RectData


def onClicked():
    print('added while creating button object')


def onClicked1(p_one, p_two, p_three):
    print(p_one, p_two, p_three)


def onClicked2(caller):
    print(caller, 'is the button instance, param =', caller.param)


def onClicked3(caller, p_one, p_two, p_three):
    print(caller.param, p_one, p_two, p_three)


def ui_elements(op: Boss_OT_base_ui):
    button = UICreator.button(
        op=op,
        rectData=RectData(10, 110, 200, 100),
        text='ButtonText',
        buttonData=ButtonData(onClick=onClicked),
        ttt='tool tip text',
        param=(1, 'two', 3.0)
    )
    # This adds callback
    button.add_onClick(onClicked1, 1, 'two', 3.0)
    button.add_onClick(onClicked2)
    button.add_onClick(onClicked3, 1, 'two', 3.0)
    button.add_onClick(lambda caller: print('lambda-', caller, caller.param))
  • Code related to callback is highlighted.

  • At line 4,8,12 and 16, you can see 4 callback functions, onClicked, onClicked1, onClicked2, onClicked3 respectively and each has different signature(parameter list).

  • onClicked, which has no parameter, is passed to ButtonData’s onClick parameter (line 25) while Button creation using buttonData=ButtonData(onClick=onClicked),

  • You can add multiple callbacks to a button, but while creating ButtonData/UI object you can pass only one callback. 1

  • Button instance has add_onClick method, similarly you’ll find add_eventName for all event for all UIs. 2

  • onClicked1 definition has three parameters, p_one,p_two,p_three. To add callback after the button is created use button.add_onClick(onClicked1, 1,'two', 3.0) with first argument being the function and following arguments being function arguments. So, in order to call a function with 3 parameters, You passed 4 arguments to add_onClick. In case you had wanted to add this callback during Button creation, you could have used buttonData=ButtonData(onClick=(onClicked1, 1,'two', 3.0)), i.e. those 4 parameters in a tuple. 3

  • Next function is onClicked2, it has a parameter named caller , which is a special argument, read about it here

  • Next function is onClicked3 , which combines the features of onClicked1 and onClicked2 , so, yes, caller and other parameters can also be used together.

  • Last is button.add_onClick(lambda caller: print('lambda-',caller,caller.param)) , lambda works, caller with lambda works too.

caller

When first argument in the callback function is named caller (it doesn’t have to be first though) , it is a special argument. It’s value is the instance of UI element that called this function. So, if the function is callback of Button’s onclick, caller’s value will be the Button instance, if function is callback of TextField’s onTextChanged, caller’s value will be the instance of TextField.

Note

its caller, all small, not Caller or CALLER

  • You don’t need to pass any value for caller parameter, while adding callback, eg. ButtonData(onClick = onClicked2) or button.add_onClick(onClick=onClicked2)

  • Since all UI have param parameter, caller in conjunction with param, makes it very flexible. With caller as first parameter in the callback, You can create logic so that same function can be callback of many events.

  • Using caller is enough in most cases and syntax is very clean.

  • If creating several buttons that call same function with different parameter, caller syntax is encouraged.

  • Using caller is always encouraged. 5

Footnotes:

1

Maybe later I will add code, so that a list of callbacks can be added while creating UI object. It’s rare but can be handy.

2

One function could be enough, with type of event also being passed, but since, Most people use VSCode or other ide that supports code suggestion, code completion, writing method of each event is more readable.

3

I know functools.partial is one way, one could use and pass one variable, this is just for convenience so that you won’t have to import partial in every file.

4

It wasn’t intentional but instead of button.add_onClick(onClicked1, 1,'two', 3.0), button.add_onClick((onClicked1, 1,'two', 3.0)) also works. i.e. you can pass one argument only, the tuple that contains those 4 elements.

5

It will be optimized in future updates.