-
Notifications
You must be signed in to change notification settings - Fork 8
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Dynamically change the interactive_ratio
on VtkRemoteView
python-side
#73
Comments
You keep having the same wrong assumption again and again. If you want to dynamically change something it needs to be in the state. The attributes on the class is to just to define the HTML content which get evaluated only once. If you reflush the layout, you will see the change but that's really not what you want to do (lot of overhead of delete/create vue component client side). So in other word, you need to generate the interactive ratio variable name and update it at the state level. That can be done at your wrapper class directly. |
What you have in mind is jupyter's trait, but that is really not what trame is doing. |
I find jupyter's traits rather intuitive. I can't help but wonder if trame could/should do this and synchronize the different attrs that may or may not be linked to state variables. From my perspective, I don't see any reason why setting the I'm thinking something like the following: class MyView(VtkRemoteView):
def __init__(self, plotter, ref=None, **kwargs):
self._INTERACTIVE_RATIO = f'{plotter._id_name}_interactive_ratio'
if 'interactive_ratio' not in kwargs:
kwargs['interactive_ratio'] = (self._INTERACTIVE_RATIO, 1)
else:
value = kwargs['interactive_ratio']
if isinstance(value, tuple):
self._INTERACTIVE_RATIO = value[0]
else:
kwargs['interactive_ratio'] = (self._INTERACTIVE_RATIO, value)
super().__init__(plotter.render_window, ref, **kwargs)
@property
def interactive_ratio(self):
return state[self._INTERACTIVE_RATIO]
@interactive_ratio.setter
def interactive_ratio(self, value):
state[self._INTERACTIVE_RATIO] = value
state.dirty(self._INTERACTIVE_RATIO) Would it make sense for all attrs of of these types of classes be wrapped this way? |
This is really helpful, thanks! I think this is something that should be implemented in PyVista's wrappings of these view classes and I'll try to make that proposal soon. |
So while I understand the jupyter/ipywidget approach make sense for tiny ui or set of controls, it does not when you create a full fledge client/server application where you have some performance consideration to keep in mind. So, in short I'm fine if you want to add that binding logic on your component, but I'm not ok putting it by default in trame. What we could technically do is to trigger a flush on the layout when someone modify an attribute that is not a variable... There will be some flashing on the client side, but it will have the behavior you expect. Then we can teach users to better support dynamic behaviors. |
For posterity, this can be done in PyVista via the following (I plan on pushing this into PyVista directly). @jourdain, is modifying the state via from pyvista.trame.views import PyVistaRemoteView
class PyVistaRemoteInteractiveRatioView(PyVistaRemoteView):
def __init__(self, plotter, **kwargs):
self._INTERACTIVE_RATIO = f'{plotter._id_name}_interactive_ratio'
self._STILL_RATIO = f'{plotter._id_name}_still_ratio'
if 'interactive_ratio' not in kwargs:
kwargs['interactive_ratio'] = (self._INTERACTIVE_RATIO, 1)
else:
value = kwargs['interactive_ratio']
if isinstance(value, tuple):
self._INTERACTIVE_RATIO = value[0]
else:
kwargs['interactive_ratio'] = (self._INTERACTIVE_RATIO, value)
if 'still_ratio' not in kwargs:
kwargs['still_ratio'] = (self._STILL_RATIO, 1)
else:
value = kwargs['still_ratio']
if isinstance(value, tuple):
self._STILL_RATIO = value[0]
else:
kwargs['still_ratio'] = (self._STILL_RATIO, value)
super().__init__(plotter, **kwargs)
def set_interactive_ratio(self, value):
self.server.state[self._INTERACTIVE_RATIO] = value
self.server.state.flush()
def set_still_ratio(self, value):
self.server.state[self._STILL_RATIO] = value
self.server.state.flush() |
In hindsight, I just noticed this is the same approach taken for toggling the remote/local modes on trame-vtk/trame_vtk/widgets/vtk/common.py Lines 554 to 558 in a8ec763
|
Anything that you plan to use dynamically in PyVista, you can do it like you described. But I would write the update like below def set_interactive_ratio(self, value):
with self.state:
self.state[self._INTERACTIVE_RATIO] = value |
Is it possible to directly change the
interactive_ratio
from theVtkRemoteView
instance itself in Python code? Take the following example with PyVista where I get access to the underlyingVtkRemoteView
instance and attempt to change theinteractive_ratio
. However, this change does not take affect (thedirty()
call was my attempt at pushing this change):I'm able to link the interactive_ratio to a variable, so I know it can be dynamically changed, but how can I do this directly from the
VtkRemoteView
instance python-side?The text was updated successfully, but these errors were encountered: