-
Notifications
You must be signed in to change notification settings - Fork 441
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
Re-reset key events in Plotter.__init__() #3622
Conversation
if hasattr(self, 'iren'): | ||
self.iren.clear_key_event_callbacks() | ||
if not hasattr(self, 'iren'): | ||
return | ||
|
||
self.iren.clear_key_event_callbacks() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Since all the other self.add_key_event()
calls are no-ops in case self.iren
doesn't exist, it seemed more readable to skip the whole method in case self.iren
is missing. It's not likely that self
will pick up the attribute mid-execution of the method.
Codecov Report
@@ Coverage Diff @@
## main #3622 +/- ##
==========================================
- Coverage 94.07% 94.03% -0.04%
==========================================
Files 83 83
Lines 18618 18630 +12
==========================================
+ Hits 17515 17519 +4
- Misses 1103 1111 +8 |
If I'm right that |
@@ -5868,6 +5870,7 @@ def on_timer(iren, event_id): | |||
# Add ren win and interactor | |||
self.iren = RenderWindowInteractor(self, light_follow_camera=False, interactor=interactor) | |||
self.iren.set_render_window(self.ren_win) | |||
self.reset_key_events() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oof. yeah, I'm concerned this will clear out existing key events from VTK which most users have come to expect. Perhaps reset_key_events()
needs to re-add those as well. I'll pull these changes soon and see which key-events are missing/needed
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks, @banesullivan!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh, and at least some VTK key events are impervious to this method, see #3647 (comment).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I added a detailed comment in #3647 about how resetting PyVista's key events have no effect on the VTK key events (though they may still conflict)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Personally, I'd like for this line to be right after the self.iren.add_observer("KeyPressEvent", self.key_press_event)
statement a few lines later but this should be fine.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Wouldn't putting that line right ater the add_observer()
call clear the newly added event as well?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think so. The reset_key_events()
method is PyVista-specific and registers callbacks with the render window interactor's _key_press_event_callbacks
. Observers are not modified by reset_key_events()
. These callbacks are then handled, at event-time, by key_press_event()
so we can register self.iren.add_observer("KeyPressEvent", self.key_press_event)
before or after reset_key_events()
Preface
I've noticed a few peculiarities with the way my plotters (on a debian linux system) close:
'q'
, the plotter closes even if I useplotter.show(auto_close=False)
, with the warning telling me that I shouldn't have closed the window by clicking exit button (which I didn't)plotter.show()
closes, I don't have aplotter.last_image
screenshot, even though I shouldbefore_close_callback
functionality is similarly broken on my system:The above version kills two birds with one stone: when I run it the plot appears, and on pressing the
'q'
key on my keyboard it prints (onmain
)If I uncomment the
before_close_callback
line, I getAgain this looks as if the plotter was closed prematurely.
With this patch the first case prints
So for some reason the plotter still gets more killed than I intended, but now
plotter.last_image
works.And the
before_close_callback
case runs successfully, silently creating the screenshot.This PR
I've realised that what must be going on is that the
'q'
key is bound to an event that kills my render window, and this happens in a platform-dependent way which is why others don't see this. We have this inBasePlotter
:pyvista/pyvista/plotting/plotting.py
Lines 1753 to 1768 in 3b97cab
And this gets called in
BasePlotter.__init__()
:pyvista/pyvista/plotting/plotting.py
Line 276 in 3b97cab
Now, the issue is that
BasePlotter
has no render window interactor, and whenPlotter.__init__()
callssuper().__init__()
, neither does it. Callingreset_key_events()
afterself.iren
is created helps in the way explained above.Open issue
I don't know why
auto_close=False
still doesn't work for me. The fact that I get the warning means that pressing the'q'
key still (even with this patch) brings me topyvista/pyvista/plotting/plotting.py
Lines 6192 to 6207 in 3b97cab
I'm wondering if this check might somehow be inadequate on my system (i.e. I have an alive render window despite
not self.ren_win.IsCurrent()
). If I temporarily remove this entire block of code from the library, thenworks almost as expected: the screenshot is created in the position that the first call to
show()
ended up with. The only weirdness is that the second call toshow()
returns immediately, with no chance to further interact with the plot. But there's no error, no segfault, and the example script continues execution fine. Not sure what to make of this all.