Skip to content
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

Fix error thrown when last video is deleted #1421

Merged
merged 11 commits into from
Aug 3, 2023
17 changes: 11 additions & 6 deletions sleap/gui/app.py
Original file line number Diff line number Diff line change
Expand Up @@ -1102,7 +1102,7 @@ def _update_gui_state(self):
self._buttons["delete node"].setEnabled(has_selected_node)
self._buttons["toggle grayscale"].setEnabled(has_video)
self._buttons["show video"].setEnabled(has_selected_video)
self._buttons["remove video"].setEnabled(has_selected_video)
self._buttons["remove video"].setEnabled(has_video)
self._buttons["delete instance"].setEnabled(has_selected_instance)
self.suggestions_dock.suggestions_form_widget.buttons[
"generate_button"
Expand Down Expand Up @@ -1207,18 +1207,23 @@ def _after_plot_update(self, frame_idx):
def _after_plot_change(self, player, frame_idx, selected_inst):
"""Called each time a new frame is drawn."""

# Store the current LabeledFrame (or make new, empty object)
self.state["labeled_frame"] = self.labels.find(
self.state["video"], frame_idx, return_new=True
)[0]
# Store the current frame_idx and LabeledFrame (or make new, empty object)
self.state["frame_idx"] = frame_idx
self.state["labeled_frame"] = (
self.labels.find(self.state["video"], frame_idx, return_new=True)[0]
if frame_idx is not None
else None
)

# Show instances, etc, for this frame
for overlay in self.overlays.values():
overlay.add_to_scene(self.state["video"], frame_idx)
overlay.redraw(self.state["video"], frame_idx)

# Select instance if there was already selection
if selected_inst is not None:
player.view.selectInstance(selected_inst)
else:
self.state["instance"] = None

if self.state["fit"]:
player.zoomToFit()
Expand Down
2 changes: 2 additions & 0 deletions sleap/gui/overlays/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,8 @@ def remove_from_scene(self):

This method does not need to be called when changing the plot to a new frame.
"""
if self.items is None:
return
for item in self.items:
self.player.scene.removeItem(item)

Expand Down
4 changes: 3 additions & 1 deletion sleap/gui/widgets/slider.py
Original file line number Diff line number Diff line change
Expand Up @@ -248,8 +248,10 @@ def value(self) -> float:
"""Returns value of slider."""
return self._val_main

def setValue(self, val: float) -> float:
def setValue(self, val: Optional[float]):
"""Sets value of slider."""
if val is None:
return
self._val_main = val
x = self._toPos(val)
self.handle.setPos(x, 0)
Expand Down
27 changes: 20 additions & 7 deletions sleap/gui/widgets/video.py
Original file line number Diff line number Diff line change
Expand Up @@ -410,22 +410,35 @@ def load_video(self, video: Video, plot=True):

self.video = video

# Is this necessary?
self.view.scene.setSceneRect(0, 0, video.width, video.height)
if self.video is None:
self.reset()
else:
# Is this necessary?
self.view.scene.setSceneRect(0, 0, video.width, video.height)

self.seekbar.setMinimum(0)
self.seekbar.setMaximum(self.video.last_frame_idx)
self.seekbar.setEnabled(True)
self.seekbar.resizeEvent()
self.seekbar.setMinimum(0)
self.seekbar.setMaximum(self.video.last_frame_idx)
self.seekbar.setEnabled(True)
self.seekbar.resizeEvent()

if plot:
self.plot()

def reset(self):
"""Reset viewer by removing all video data."""
# Reset view and video
self.video = None
self.state["frame_idx"] = None
self.view.clear()
self.view.setImage(
QImage(sleap.util.get_package_file("sleap/gui/background.png"))
)

# Handle overlays and gui state in callback
frame_idx = None
selected_instance = None
self.changedPlot.emit(self, frame_idx, selected_instance)

# Reset seekbar
self.seekbar.setMaximum(0)
self.seekbar.setEnabled(False)

Expand Down
Loading