def close(self): # we play it safe... (the graph_editor/module_manager should have # disconnected us by now) for input_idx in range(len(self.get_input_descriptions())): self.set_input(input_idx, None) # get rid of our reference del self._splatMapper del self._otf del self._ctf del self._volumeProperty del self._volume del self._object_dict ColourDialogMixin.close(self) # we have to call this mixin close so that all inspection windows # can be taken care of. They should be taken care of in anycase # when the viewFrame is destroyed, but we like better safe than # sorry IntrospectModuleMixin.close(self) # take care of our own window if self._view_frame is not None: self._view_frame.Destroy() del self._view_frame
def close(self): # shut down the orientationWidget/Actor stuff self._orientation_widget.Off() self._orientation_widget.SetInteractor(None) self._orientation_widget.SetOrientationMarker(None) del self._orientation_widget del self._annotated_cube_actor # take care of scalarbar self._showScalarBarForProp(None) # this is standard behaviour in the close method: # call set_input(idx, None) for all inputs for idx in range(self._numDataInputs): self.set_input(idx, None) # take care of the sliceDirections self.sliceDirections.close() del self.sliceDirections # the points self.selectedPoints.close() del self.selectedPoints # take care of the threeD objects self._tdObjects.close() del self._tdObjects # the implicits self._implicits.close() del self._implicits # don't forget to call the mixin close() methods IntrospectModuleMixin.close(self) ColourDialogMixin.close(self) # unbind everything that we bound in our __init__ del self._outline_source del self._outline_actor del self._cube_axes_actor2d del self._voi_widget #del self._extractVOI del self._cInteractorStyle # make SURE there are no props in the Renderer self._threedRenderer.RemoveAllViewProps() # take care of all our bindings to renderers del self._threedRenderer if BACKGROUND_RENDERER: # also do the background renderer self._background_renderer.RemoveAllViewProps() del self._background_renderer # the remaining bit of logic is quite crucial: # we can't explicitly Destroy() the frame, as the RWI that it contains # will only disappear when it's reference count reaches 0, and we # can't really force that to happen either. If you DO Destroy() the # frame before the RW destructs, it will cause the application to # crash because the RW assumes a valid WindowId in its dtor # # we have two solutions: # 1. call a WindowRemap on the RenderWindows so that they reparent # themselves to newly created windowids # 2. attach event handlers to the RenderWindow DeleteEvent and # destroy the containing frame from there # # method 2 doesn't alway work, so we use WindowRemap # hide it so long #self.threedFrame.Show(0) #self.threedFrame.threedRWI.GetRenderWindow().SetSize(10,10) #self.threedFrame.threedRWI.GetRenderWindow().WindowRemap() # finalize should be available everywhere self.threedFrame.threedRWI.GetRenderWindow().Finalize() # zero the RenderWindow self.threedFrame.threedRWI.SetRenderWindow(None) # and get rid of the threedRWI interface del self.threedFrame.threedRWI # all the RenderWindow()s are now reparented, so we can destroy # the containing frame self.threedFrame.Destroy() # unbind the _view_frame binding del self.threedFrame # take care of the objectAnimationFrame self.objectAnimationFrame.Destroy() del self.objectAnimationFrame # take care of the controlFrame too self.controlFrame.Destroy() del self.controlFrame # if we don't give time up here, things go wrong (BadWindow error, # invalid glcontext, etc). we'll have to integrate this with the # eventual module front-end / back-end split. This time-slice # allows wx time to destroy all windows which somehow also leads # to VTK being able to deallocate everything that it has. wx.SafeYield()