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
Basic "play" functionality (animate a dimension) #607
Conversation
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.
This looks great @tlambert03! Thanks for the contribution - a play button is on our 0.3.0
roadmap #420 but no one was working on it yet, so great timing!
A couple quick comments - using another thread so the QTimer is not blocking might be a good idea, but I can also see reasons why it might be best to just let it play without being able to change anything. How do @royerloic @jni feel about the expected behavior?
If we do want to use another thread @AhmetCanSolak might have ideas on how to do this best too.
I'll also play around with some example datasets and see how it feels too.
Your comment about QtDims.stop
is also interesting - we might want to hook up an event from the viewer to trigger stopping when the layers data changes. Right now we have a function viewer._on_layers_change
that gets called when changes like that happen, we might want to make the viewer emit an event layers_change
that will stop an animation, but again maybe that relates to what expectations we have about interactivity during playing.
If you want to add play buttons in this PR too that would be great - you'll need to look at our contributing guidelines for adding icons, but we can also merge without it and then make a followup PR later if not.
OK, made the changes mentioned above, and I moved the animation timer to it's own @AhmetCanSolak, I realize now that you were going to take on the play button thing, (sorry!) so please have a look when you get a chance and let me know what you would do differently... In particular, you might have thoughts on the issues below... Remaining problems:
I'll try to take a look at adding icons and play buttons soon... |
for the Gracefully failing / debouncing the animation timer sounds good. The |
I made some debouncing/performance changes that I think worked pretty well. The The gif below shows the GUI remains responsive to start/stop requests and layer events even with 6 3D stacks "playing" as fast as 1000fps (obviously vispy isn't keeping up, but the gui remains responsive). unfortunately, I broke my tests, since now it's waiting on a vispy draw event that never occurs in the test and so it appears to advance only a single frame. I could either mock the set_point function, or just relax the test... |
That's amazing!! If you can try using @patch.object(visual, '_on_data_change', wraps=visual._on_data_change)
def test_ndisplay_change(mocked_method, ndisplay=3):
viewer.dims.ndisplay = ndisplay
mocked_method.assert_called_once() |
Co-Authored-By: Juan Nunez-Iglesias <juan.nunez-iglesias@monash.edu>
@tlambert03 just gave this a try - everything is working great! One question though - when you click in the slider during an animation it only skips backward / forward one point instead of jumping to that point. You can click and drag on the slider to get back to that point, but I feel like the functionality would be more useful if it just automatically jumped. Was there a reason you made it just skip one instead of jump? One of the usage modes I am imagining is that you're playing and then you see something cool and you want to just click the slider and have it automatically jump back to that point so you can watch it again. You can't quite do that so easily right now. I also seem to remember seeing a comment asking for help thinking about the tests, but I can't find it so you may have deleted it. Sorry that's such a pain right now. My recommendation is to relax so we can merge - maybe leave the more strict test in there as a comment though so we can always revisit in the future if something breaks. |
Thanks a lot @sofroniewn
see the "note" in the second paragraph of my comment above: #607 (comment) yeah, I deleted the request for help; I thought about a new approach and didn't want anyone wasting their time. The new approach is working a bit better, but still failing. I'm determined to get it working and will post when ready for final review. |
Ah - totally miss understood that comment about the current behavior - I got it now. I actually thought the current behavior was to jump, not just increment left / right by one, even with no animation. I completely agree this should be a separate PR, and I'd wait until this one merges to open it. I think it would be nice if jumped for both non-animation and animation usage. Good luck with the tests. Let us know when you are satisfied with them and then I will merge |
I think the tests are stable now. I re-triggered the cirrus tests a few more times on my account and they work (excluding windows). In case anyone is curious, I focused on testing @jni may want to comment again on #607 (comment) sorry everyone for the many commits and emails this PR probably caused! things to do in another PR:
|
This looks finished to me @tlambert03 - I think that seems like a good strategy on the tests. I will leave this until end of day today in case @jni wants to weigh in once more and resolve his requested changes, but judging from his comment I think he trusts this is the right direction, and I will merge at that point |
Requested changes have now been made and PR has been ready for 24hrs
Description
This PR adds a "play" method to
qt_dims.QtDims
to animate changing the slice setpoint (e.g. for a time axis). I'm sure this was something you were going to implement eventually but I didn't see any discussion yet in the issue tracker... This was just how I implemented it, so feel free to "freeze" or disregard this PR if there were reasons for holding off on this functionality until later. Currently there is no button in the GUI Window, just a keybinding (ctrl-alt-P
), and a couple new methods onQtDims
. Similarly, changing playback speed or the axis being animated requires using the method directly.Some other things that should be addressed before any sort of merge...
QTimer
driving the animation appears to halt on any mouseover event in the main window causing a delay in animation. That might be fine (might even be the desired compromise for performance), but I thought it was worth mentioning. I suppose it could run in a different thread to prevent that?QtDims.stop()
method halts the animation. So if the user changes the number of displayed dims, the "animated" axis may no longer be visible, yet the timer and the corresponding computation continue. this can create a performance/lag issue.Type of change
References
https://doc.qt.io/qt-5/qtimer.html
How has this been tested?
napari._qt.tests.test_qt_viewer.test_play_axis
) for my feature covers playing the 0th axis in a 3D image, asserting that the play method works (i.e. thedims.point
has changed the expected number of frames after some wait interval), and asserting that the stop method actually works to prevent additionalset_point
callsFinal checklist: