[vtkusers] About MouseEvents.py example

Elvis Stansvik elvis.stansvik at orexplore.com
Thu Jun 16 13:08:27 EDT 2016


2016-06-16 17:33 GMT+02:00 David Gobbi <david.gobbi at gmail.com>:

> On Thu, Jun 16, 2016 at 9:08 AM, Elvis Stansvik <
> elvis.stansvik at orexplore.com> wrote:
>
>> 2016-06-16 16:08 GMT+02:00 Elvis Stansvik <elvis.stansvik at orexplore.com>:
>>
>>> 2016-06-16 15:52 GMT+02:00 Elvis Stansvik <elvis.stansvik at orexplore.com>
>>> :
>>>
>>>> The MouseEvents.py example [1] currently does:
>>>>
>>>> class MyInteractorStyle(vtk.vtkInteractorStyleTrackballCamera):
>>>>
>>>>     def __init__(self,parent=None):
>>>>
>>>> self.AddObserver("MiddleButtonPressEvent",self.middleButtonPressEvent)
>>>>
>>>> self.AddObserver("MiddleButtonReleaseEvent",self.middleButtonReleaseEvent)
>>>>
>>>>     def middleButtonPressEvent(self,obj,event):
>>>>         print("Middle Button pressed")
>>>>         self.OnMiddleButtonDown()
>>>>         return
>>>>
>>>>     def middleButtonReleaseEvent(self,obj,event):
>>>>         print("Middle Button released")
>>>>         self.OnMiddleButtonUp()
>>>>         return
>>>>
>>>> But I don't understand the reason for calling e.g.
>>>> self.OnMiddleButtonDown() ? Since this is not an override of a virtual
>>>> function (which is not possible in Python), but simply adding another
>>>> observer, I don't think it is needed? (..and I would think it would mean
>>>> OnMiddleButtonDown is called twice, right?).
>>>>
>>>
>>> Sorry, I realize I wasn't really clear here: What I mean is that, if the
>>> interactor style above is used, the behavior of
>>> vtkInteractorStyleTrackballCamera (the base class) will still be there,
>>> even if the call to self.OnMiddleButtonDown() is removed, since the base
>>> class will observe the interactor. That's why I don't understand the need
>>> for the self.OnMiddleButtonDown() call in the example.
>>>
>>> This ties in to my other question (another mail), since what I want to
>>> do is to actually override the behavior of the base interactor style
>>> (similar to how you can in C++, but I need to find some other mechanism to
>>> do so, overriding of virtual functions won't work from Python).
>>>
>>
>> Sorry, I confused myself with all my mails, it actually was in the
>> original mail in this thread I brought up this question.
>>
>> Perhaps I should tell a little more about my goal. I'm building an
>> application with VTK, and in some cases I expect that I want to make use of
>> VTKs interactor + interactor style machinery, and leverage the built-in
>> interactor styles (such as vtkInteractorStyleTrackballCamera), but at
>> the same time I might want to override behavior, and also be able to decide
>> whether I want to override a particular event or not at runtime, when
>> handling the event. I also suspect that I might want to modify the event
>> information before passing it on.
>>
>> E.g. in C++ I would just override the virtual method, and in my override
>> I'd be able decide whether I want to do something special or call the base
>> class implementation.
>>
>> It seem there's no easy way of doing the equivalent in Python? At least I
>> haven't found any. I've found some mentions in the vtkCommand docs about
>> being able to stop propagation of an event to observers with lower
>> priority. But I haven't found any exampels of this in Python, and it also
>> seems that the docs in vtkCommand about callData are not applicable to
>> Python? And also, with that solution, I'd have to install observers
>> directly on the interactor, like the interactor style does, in order to end
>> up in the same event propagation chain so to speak.
>>
>> I'd love to hear how others have solved the problem of custom interaction
>> behavior in Python, while still being able to leverage (parts of) the
>> functionality provided by the built-in interactor styles.
>>
>
> In C++, a callback can return "true" to stop event propagation:
>
>   // Description:
>   // This method invokes an event and return whether the event was
>   // aborted or not. If the event was aborted, the return value is 1,
>   // otherwise it is 0.
>   int InvokeEvent(unsigned long event, void *callData);
>   int InvokeEvent(unsigned long event);
>
> When this feature was added for C++, it wasn't added to
> vtkPythonCommand.cxx (an oversight), so vtkPythonCommand.cxx would have to
> be modified to add this behavior for Python.
>

Ah, I see.


>
> Regarding calldata, see the following merge request (now merged):
> https://gitlab.kitware.com/vtk/vtk/merge_requests/1543/commits
> If Hasting happens to be reading this, please note that commit messages
> should be a wee bit more descriptive...
>

Thanks for the pointer, that's good. Though I see now that the only
supported types are strings, floats, ints and vtk.vtkObject. In my case I
would have been interested in QMouseEvent, since I read that QVTKWidget
will use that as callData on the C++ side and was hoping the could have
been true in Python (but perhaps it wouldn't have been due to other
reasons..?).


> I can't say much about the rest.  The interactors aren't my favorite part
> of VTK.
>

Thanks a lot for taking the time to answer anyway! I also find the
interactors a little wonky.

Elvis


>
>  - David
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://public.kitware.com/pipermail/vtkusers/attachments/20160616/b89b7057/attachment.html>


More information about the vtkusers mailing list