enthought / enthought/mayavi

Unable to reattatch on_mouse_pick to figure

Open
#1,204 0 comments 1 reaction 0 assignees View on GitHub
Dominant language
Python
Stars
1.4k
Forks
316
Avg merge
7h 44m
Merged PRs (30d)
5

Description

Windows 7/64bit and Windows 10/64bit
mayavi 4.8.1
python 3.8.9
Basically the same issue as in [this very old subject](https://stackoverflow.com/questions/23435986/mayavi-help-in-resetting-mouse-picker-and-connecting-wx-event-to-on-trait-chan).
```
def clear_figure(self):
for child in self.scene.mayavi_scene.children:
child.remove()
```

The solution of calling ```remove``` method on all children of the scene kinda works but not really. It will let you attach the picker, but it will add it multiple times - it removes the connection, but not the callback itself.

I think the issue comes from conditionals in `callback_added` method, or more precisely from callbacks dictionaries that don't get cleared after removing their connection in `callback_removed` method (`if not type in self._picker_callback_nbs:`, `if not self._mouse_mvt_callback_nb:`, `if not button in self._mouse_press_callback_nbs:`, `if not button in self._mouse_release_callback_nbs:`). I managed to fix that issue by clearing the callbacks dictionaries in "mouse_pick_dispatcher.py". I did it by modifying the `callback_removed` method (I marked added lines with #mod):
```
def callback_removed(self, item):
""" Clean up the unnecessary VTK callbacks.
"""
callback, type, button = item

# If the picker is no longer needed, clean up its observers.
if not [t for c, t, b in self.callbacks if t == type]:
picker = self._active_pickers[type]
picker.remove_observer(self._picker_callback_nbs[type])
del self._active_pickers[type]
del self._picker_callback_nbs[type] #mod

# If there are no longer callbacks on the button, clean up
# the corresponding observers.
if not [b for c, t, b in self.callbacks if b == button]:
self.scene.scene.interactor.remove_observer(
self._mouse_press_callback_nbs[button])
del self._mouse_press_callback_nbs[button] #mod
self.scene.scene.interactor.remove_observer(
self._mouse_release_callback_nbs[button])
del self._mouse_release_callback_nbs[button] #mod
if len(self.callbacks) == 0 and self._mouse_mvt_callback_nb:
self.scene.scene.interactor.remove_observer(
self._mouse_mvt_callback_nb)
self._mouse_mvt_callback_nb = 0
```

I couldn't find similar solution posted anywhere, so I thought to post it here. I'm new to github so I dunno how/where to propose a fix. I hope someone will find it useful :).

Contributor guide

No contributing guide indexed for this repository

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.