# Pass values throught InvokeEvent callback

**URL:** <https://discourse.vtk.org/t/pass-values-throught-invokeevent-callback/4152>\
**Category:** Development\
**Created:** [September 4, 2020, 12:43pm UTC](https://discourse.vtk.org/t/pass-values-throught-invokeevent-callback/4152 "2020-09-04T12:43:02Z")\
**Posts on this page:** 15\
**Page:** 1

<div class="post-metadata">

**Author:** ![Ennio\_Bolondi](https://discourse.vtk.org/user_avatar/discourse.vtk.org/ennio_bolondi/32/2098_2.png) [@Ennio\_Bolondi](https://discourse.vtk.org/u/Ennio_Bolondi)\
**Post date:** [September 4, 2020, 12:43pm UTC](https://discourse.vtk.org/t/pass-values-throught-invokeevent-callback/4152/1 "2020-09-04T12:43:02Z")

</div>

Hi, I’m exploring how the vtk server “event system” works.  
I would like to ask a question about the “InvokeEvent” operation (server side).  
Into the “protocols.py” there is the “mouseInteraction” method which has the [following line](https://gitlab.kitware.com/vtk/vtk/-/blob/master/Web/Python/vtkmodules/web/protocols.py#L128):

```
self.getApplication().InvokeEvent('UpdateEvent')

```

Into the class “vtk\_override\_protocols.py” the event is intercepted by the method “addRenderObserver” which prepare the “callback” in the following way ([click here to see the code on github](https://gitlab.kitware.com/vtk/vtk/blob/master/Web/Python/vtkmodules/web/protocols.py#L468)):

```
observerCallback = lambda *args, **kwargs: self.pushRender(realViewId)
tag = self.getApplication().AddObserver('UpdateEvent', observerCallback)

```

So in that way each time the “ **UpdateEvent** ” is fired, the “ **pushRender** ” is invoked. That’s great!

My question is:  
How can I send a value throught the “InvokeEvent” call?  
Basically I need to pass a timestamp, so for example:

```
timeStamp = datetime.now().strftime("%d/%m/%Y %H:%M:%S")
self.getApplication().InvokeEvent('UpdateEvent', timeStamp)

```

And I would like to read the value in the “ **pushRender** ” method.  
Is that possible? [Here](https://vtk.org/doc/release/5.0/html/a01761.html) I found some hints, but this is for the c++ staff, not for the python ones.

Thanks and regards  
Ennio

---

<div class="post-metadata">

**Author:** ![lassoan](https://discourse.vtk.org/user_avatar/discourse.vtk.org/lassoan/32/50_2.png) [@lassoan](https://discourse.vtk.org/u/lassoan)\
**Post date:** [September 6, 2020, 8:54pm UTC](https://discourse.vtk.org/t/pass-values-throught-invokeevent-callback/4152/2 "2020-09-06T20:54:49Z")

</div>

You can pass a few simple data types and objects that are derived from `vtkObject` class by using `@vtk.calldata_type` decorator. See detailed information here: [https://www.slicer.org/wiki/Documentation/Nightly/Developers/FAQ#How\_can\_I\_access\_callData\_argument\_in\_a\_VTK\_object\_observer\_callback\_function](https://www.slicer.org/wiki/Documentation/Nightly/Developers/FAQ#How_can_I_access_callData_argument_in_a_VTK_object_observer_callback_function)

@dgobbi is there a user documentation of VTK’s Python wrapper? I couldn’t find a relevant section in in [VTK API documentation](https://vtk.org/doc/nightly/html/index.html) and full-text search is not enabled, so I couldn’t even see if “vtk.calldata\_type” is mentioned.

---

<div class="post-metadata">

**Author:** ![Ennio\_Bolondi](https://discourse.vtk.org/user_avatar/discourse.vtk.org/ennio_bolondi/32/2098_2.png) [@Ennio\_Bolondi](https://discourse.vtk.org/u/Ennio_Bolondi)\
**Post date:** [September 7, 2020, 7:11am UTC](https://discourse.vtk.org/t/pass-values-throught-invokeevent-callback/4152/3 "2020-09-07T07:11:56Z")

</div>

Thank you Andras,  
at the end I figurated it out.  
Thank you anyway for sharing me a couple of useful links and documentations.  
Still have a couple of issues when passing the complex objects, but I will (hopefully) fix them in the next days.

bye,  
Ennio

---

<div class="post-metadata">

**Author:** ![Ennio\_Bolondi](https://discourse.vtk.org/user_avatar/discourse.vtk.org/ennio_bolondi/32/2098_2.png) [@Ennio\_Bolondi](https://discourse.vtk.org/u/Ennio_Bolondi)\
**Post date:** [September 8, 2020, 7:17am UTC](https://discourse.vtk.org/t/pass-values-throught-invokeevent-callback/4152/4 "2020-09-08T07:17:25Z")

</div>

Hi Andras,  
just a quick question: I would like to pass a string or an vtk\_object to the callback.  
At the moment only a simple integer has been sent as value.  
I tried to use VTK\_STRING but the program unexpectedly exited (so I think an error has accured).

I really can’t figure out why is not working.  
I just substituted the @vtk.calldata\_type(vtk.VTK\_LONG) with @vtk.calldata\_type(vtk.VTK\_STRING).  
Is there something wrong here?

Thanks,  
Ennio

---

<div class="post-metadata">

**Author:** ![lassoan](https://discourse.vtk.org/user_avatar/discourse.vtk.org/lassoan/32/50_2.png) [@lassoan](https://discourse.vtk.org/u/lassoan)\
**Post date:** [September 8, 2020, 12:59pm UTC](https://discourse.vtk.org/t/pass-values-throught-invokeevent-callback/4152/5 "2020-09-08T12:59:26Z")

</div>

@dgobbi is there a way to pass a string from Python as event data?

@Ennio_Bolondi until you figure out how to send a single string, you can use vtkStringArray object.

---

<div class="post-metadata">

**Author:** ![efahl](https://discourse.vtk.org/user_avatar/discourse.vtk.org/efahl/32/1087_2.png) [@efahl](https://discourse.vtk.org/u/efahl)\
**Post date:** [September 8, 2020, 1:16pm UTC](https://discourse.vtk.org/t/pass-values-throught-invokeevent-callback/4152/6 "2020-09-08T13:16:05Z")

</div>

Sure, it’s the example in the doc string for `calldata_type`:

```auto
Help on function calldata_type in vtk:

vtk.calldata_type = calldata_type(type)
    set_call_data_type(type) -- convenience decorator to easily set the CallDataType attribute
    for python function used as observer callback.
    For example:

    import vtkmodules.util.calldata_type
    import vtkmodules.util.vtkConstants
    import vtkmodules.vtkCommonCore import vtkCommand, vtkLookupTable

    @calldata_type(vtkConstants.VTK_STRING)
    def onError(caller, event, calldata):
        print("caller: %s - event: %s - msg: %s" % (caller.GetClassName(), event, calldata))

    lt = vtkLookupTable()
    lt.AddObserver(vtkCommand.ErrorEvent, onError)
    lt.SetTableRange(2,1)

```

Or without bothering to import, you can use a string name for the type:

````auto
@vtk.calldata_type('string0')
def vtkErrorEventHandler(caller, event, calldata):```
````

---

<div class="post-metadata">

**Author:** ![Ennio\_Bolondi](https://discourse.vtk.org/user_avatar/discourse.vtk.org/ennio_bolondi/32/2098_2.png) [@Ennio\_Bolondi](https://discourse.vtk.org/u/Ennio_Bolondi)\
**Post date:** [September 8, 2020, 1:34pm UTC](https://discourse.vtk.org/t/pass-values-throught-invokeevent-callback/4152/7 "2020-09-08T13:34:27Z")

</div>

Thank you Eric and Andreas, ok I’ll give a second chance.  
I wrote the same code you have in the example above, but maybe I misspelled it.  
Thanks and regards  
Ennio

---

<div class="post-metadata">

**Author:** ![efahl](https://discourse.vtk.org/user_avatar/discourse.vtk.org/efahl/32/1087_2.png) [@efahl](https://discourse.vtk.org/u/efahl)\
**Post date:** [September 8, 2020, 1:40pm UTC](https://discourse.vtk.org/t/pass-values-throught-invokeevent-callback/4152/8 "2020-09-08T13:40:34Z")

</div>

Oops, I didn’t add anything to what you already knew. Do you know the C++ type of the object being passed, or is all your code pure Python? I’m guessing that mapping the object to `VTK_LONG` is simply casting and sending the address of whatever object is coming out of the C++ call, which is why it works. What’s the value of that parameter on the receiving end when you use `VTK_LONG`?

More importantly, does `InvokeEvent` have a second parameter? I can’t find its definition to verify, but all the examples I’ve scanned simply allow a single, event name parameter.

---

<div class="post-metadata">

**Author:** ![efahl](https://discourse.vtk.org/user_avatar/discourse.vtk.org/efahl/32/1087_2.png) [@efahl](https://discourse.vtk.org/u/efahl)\
**Post date:** [September 8, 2020, 1:53pm UTC](https://discourse.vtk.org/t/pass-values-throught-invokeevent-callback/4152/9 "2020-09-08T13:53:17Z")

</div>

I’m getting it to work in a little example. Maybe start here and work up?

```auto
import vtk

@vtk.calldata_type('string0')
def vtkErrorEventHandler(object, event, callData):
    print(object, event, callData)

o = vtk.vtkObject()
o.AddObserver(vtk.vtkCommand.AnyEvent, vtkErrorEventHandler)

print(o.InvokeEvent('Blah', 'Hello, world!'))

```

When run:

```auto
vtkObject (000002332BBF5EB0)
  Debug: Off
  Modified Time: 62
  Reference Count: 1
  Registered Events:
    Registered Observers:
      vtkObserver (000002332BD4F4E0)
        Event: 1
        EventName: AnyEvent
        Command: 000002332BBF5230
        Priority: 0
        Tag: 1

 NoEvent Hello, world!
0

```

---

<div class="post-metadata">

**Author:** ![Ennio\_Bolondi](https://discourse.vtk.org/user_avatar/discourse.vtk.org/ennio_bolondi/32/2098_2.png) [@Ennio\_Bolondi](https://discourse.vtk.org/u/Ennio_Bolondi)\
**Post date:** [September 8, 2020, 2:27pm UTC](https://discourse.vtk.org/t/pass-values-throught-invokeevent-callback/4152/10 "2020-09-08T14:27:13Z")

</div>

Ok finally it worked.  
I figured out what was the problem: I was passing a **python object** which was “”“containing”“” a string.  
In other words: I didn’t “typitize” it as a string.

**So in my final solution I used** :

```auto
self.getApplication().InvokeEvent('UpdateEvent', str(stringArgument)) # WORKING SOLUTION

```

**instead of:**

```auto
self.getApplication().InvokeEvent('UpdateEvent', stringArgument)

```

So finally it’s working with @vtk.calldata\_type(vtk.VTK\_STRING)

Thank you so much!  
Ennio

PS:

> What’s the value of that parameter on the receiving end when you use `VTK_LONG` ?

I printed it out and it is: ‘8’  
“VTK\_STRING” is: ‘13’

And I’m happy to say that it’s working with the following as well:

```auto
@vtk.calldata_type('string0') # THIS ONE WORKS AS WELL :-)

```

Thanks!!

PPS:  
last question: I was wondering if there is a way to pass an Object (maybe it could be usefull in the future). In the meanwhile I can use a string array as “Andreas” suggested.

---

<div class="post-metadata">

**Author:** ![dgobbi](https://discourse.vtk.org/user_avatar/discourse.vtk.org/dgobbi/32/18_2.png) [@dgobbi](https://discourse.vtk.org/u/dgobbi)\
**Post date:** [September 8, 2020, 2:40pm UTC](https://discourse.vtk.org/t/pass-values-throught-invokeevent-callback/4152/11 "2020-09-08T14:40:27Z")

</div>

Hi Andras, I’ve been on vacation and haven’t been able to read through this thread yet, @jcfr implemented parts of the python event code and he might be able to answer.

---

<div class="post-metadata">

**Author:** ![lassoan](https://discourse.vtk.org/user_avatar/discourse.vtk.org/lassoan/32/50_2.png) [@lassoan](https://discourse.vtk.org/u/lassoan)\
**Post date:** [September 8, 2020, 3:24pm UTC](https://discourse.vtk.org/t/pass-values-throught-invokeevent-callback/4152/12 "2020-09-08T15:24:10Z")

</div>

> [@dgobbi](#):
>
> jcfr implemented parts of the python event code and he might be able to answer.

Thank you, I think @Ennio_Bolondi figured it out.

> [@Ennio\_Bolondi](#):
>
> I was wondering if there is a way to pass an Object

You can pass any objects derived from vtkObject.

If you want to pass custom Python objects, then you can serialize it to string: create a json representation manually; or use pickle to get a byte array and convert to string using base-64 encoding.

---

<div class="post-metadata">

**Author:** ![Ennio\_Bolondi](https://discourse.vtk.org/user_avatar/discourse.vtk.org/ennio_bolondi/32/2098_2.png) [@Ennio\_Bolondi](https://discourse.vtk.org/u/Ennio_Bolondi)\
**Post date:** [September 8, 2020, 3:30pm UTC](https://discourse.vtk.org/t/pass-values-throught-invokeevent-callback/4152/13 "2020-09-08T15:30:42Z")

</div>

Thank you to everyone.  
I think I’m definitely ready to master the callbacks arguments 🙂  
Really appreciate the time and patience you put in this thread  
Ennio

---

<div class="post-metadata">

**Author:** ![efahl](https://discourse.vtk.org/user_avatar/discourse.vtk.org/efahl/32/1087_2.png) [@efahl](https://discourse.vtk.org/u/efahl)\
**Post date:** [September 8, 2020, 4:37pm UTC](https://discourse.vtk.org/t/pass-values-throught-invokeevent-callback/4152/14 "2020-09-08T16:37:48Z")

</div>

Ennio, my understanding of `calldata_type` came from looking at its implementation in util/misc.py. Here’s the part I find the most interesting:

```auto
    supported_call_data_types = ['string0', vtkCommonCore.VTK_STRING,
            vtkCommonCore.VTK_OBJECT, vtkCommonCore.VTK_INT,
            vtkCommonCore.VTK_LONG, vtkCommonCore.VTK_DOUBLE, vtkCommonCore.VTK_FLOAT]

```

---

<div class="post-metadata">

**Author:** ![Adam\_Hendry](https://discourse.vtk.org/user_avatar/discourse.vtk.org/adam_hendry/32/5571_2.png) [@Adam\_Hendry](https://discourse.vtk.org/u/Adam_Hendry)\
**Post date:** [July 29, 2022, 12:48am UTC](https://discourse.vtk.org/t/pass-values-throught-invokeevent-callback/4152/15 "2022-07-29T00:48:38Z")

</div>

Ennio, in the VTK C++ source, the second parameter (`callData`) is a `void*`. From the [VTK Python Wrappers docs](https://vtk.org/doc/nightly/html/md__builds_gitlab_kitware_sciviz_ci_Documentation_Doxygen_PythonWrappers.html):

> a `void*` pointer can accept a pointer in two different ways: either from an Python object that supports the Python buffer protocol (this includes all numpy arrays along with the Python bytes and bytearray types), or from a string that contains a mangled pointer for the form ` '_hhhhhhhhhhhh_p_void'`, where `'hhhhhhhhhhhh'` is the hexadecimal address. Return-valid `void*` will always be a string containing the mangled pointer.

This is why wrapping it in a `str()` worked: you called the object’s ` __str__ ()` that returned its string representation.

Note that

- Python 3 `bytes` = Python 2.7 `str`
- Python 3 `str` = Python 2.7 `unicode`

However, `str` works for me as well.
