Пример #1
0
    def __init__(self,
                 parentApplet,
                 topLevelOperatorView,
                 additionalMonitoredSlots=[],
                 centralWidgetOnly=False,
                 crosshair=True,
                 is_3d_widget_visible=False):
        """
        Constructor.  **All** slots of the provided *topLevelOperatorView* will be monitored for changes.
        Changes include slot resize events, and slot ready/unready status changes.
        When a change is detected, the `setupLayers()` function is called, and the result is used to update the list of layers shown in the central widget.

        :param topLevelOperatorView: The top-level operator for the applet this GUI belongs to.
        :param additionalMonitoredSlots: Optional.  Can be used to add additional slots to the set of viewable layers (all slots from the top-level operator are already monitored).
        :param centralWidgetOnly: If True, provide only a central widget without drawer or viewer controls.
        """
        super(LayerViewerGui, self).__init__()

        self._stopped = False
        self._initialized = False
        self.__cleanup_fns = []

        self.threadRouter = ThreadRouter(self)  # For using @threadRouted

        self.topLevelOperatorView = topLevelOperatorView

        observedSlots = []

        for slot in list(topLevelOperatorView.inputs.values()) + list(
                topLevelOperatorView.outputs.values()):
            if slot.level == 0 or slot.level == 1:
                observedSlots.append(slot)

        observedSlots += additionalMonitoredSlots

        self._orphanOperators = [
        ]  # Operators that are owned by this GUI directly (not owned by the top-level operator)
        self.observedSlots = []
        for slot in observedSlots:
            if slot.level == 0:
                if not isinstance(slot.stype, ArrayLike):
                    # We don't support visualization of non-Array slots.
                    continue
                # To be monitored and updated correctly by this GUI, slots must have level=1, but this slot is of level 0.
                # Pass it through a trivial "up-leveling" operator so it will have level 1 for our purposes.
                opPromoteInput = OpWrapSlot(
                    parent=slot.getRealOperator().parent)
                opPromoteInput.Input.connect(slot)
                slot = opPromoteInput.Output
                self._orphanOperators.append(opPromoteInput)

            # Each slot should now be indexed as slot[layer_index]
            assert slot.level == 1
            self.observedSlots.append(slot)
            slot.notifyInserted(bind(self._handleLayerInsertion))
            self.__cleanup_fns.append(
                partial(slot.unregisterInserted,
                        bind(self._handleLayerInsertion)))

            slot.notifyRemoved(bind(self._handleLayerRemoval))
            self.__cleanup_fns.append(
                partial(slot.unregisterRemoved,
                        bind(self._handleLayerRemoval)))

            for i in range(len(slot)):
                self._handleLayerInsertion(slot, i)

        self.layerstack = LayerStackModel()
        self.saved_layer_visibilities = None

        self._initCentralUic()

        self._initEditor(crosshair=crosshair,
                         is_3d_widget_visible=is_3d_widget_visible)
        self.__viewerControlWidget = None
        if not centralWidgetOnly:
            self.initViewerControlUi(
            )  # Might be overridden in a subclass. Default implementation loads a standard layer widget.
            #self._drawer = QWidget( self )
            self.initAppletDrawerUi(
            )  # Default implementation loads a blank drawer from drawer.ui.

        self._up_to_date = False

        # By default, we start out disabled until we have at least one layer.
        self.centralWidget().setEnabled(False)
Пример #2
0
    def __init__(self, topLevelOperator):
        """
        Args:
            observedSlots   - A list of slots that we'll listen for changes on.
                               Each must be a multislot with level=1 or level=2.
                               The first index in the multislot is the image index. 
        """
        super(LayerViewerGui, self).__init__()

        self.threadRouter = ThreadRouter(self)  # For using @threadRouted

        self.topLevelOperator = topLevelOperator

        observedSlots = []

        for slot in topLevelOperator.inputs.values(
        ) + topLevelOperator.outputs.values():
            if slot.level == 1 or slot.level == 2:
                observedSlots.append(slot)

        self.observedSlots = []
        for slot in observedSlots:
            if slot.level == 1:
                # The user gave us a slot that is indexed as slot[image]
                # Wrap the operator so it has the right level.  Indexed as: slot[image][0]
                opPromoteInput = OperatorWrapper(Op1ToMulti,
                                                 graph=slot.operator.graph)
                opPromoteInput.Input.connect(slot)
                slot = opPromoteInput.Outputs

            # Each slot should now be indexed as slot[image][sub_index]
            assert slot.level == 2
            self.observedSlots.append(slot)

        self.layerstack = LayerStackModel()

        self.initAppletDrawerUi(
        )  # Default implementation loads a blank drawer.
        self.initCentralUic()
        self.__viewerControlWidget = None
        self.initViewerControlUi()

        self.initEditor()

        self.imageIndex = -1
        self.lastUpdateImageIndex = -1

        def handleDatasetInsertion(slot, imageIndex):
            if self.imageIndex == -1 and self.areProvidersInSync():
                self.setImageIndex(imageIndex)

        for provider in self.observedSlots:
            provider.notifyInserted(bind(handleDatasetInsertion))

        def handleDatasetRemoval(slot, index, finalsize):
            if finalsize == 0:
                # Clear everything
                self.setImageIndex(-1)
            elif index == self.imageIndex:
                # Our currently displayed image is being removed.
                # Switch to the first image (unless that's the one being removed!)
                newIndex = 0
                if index == newIndex:
                    newIndex = 1
                self.setImageIndex(newIndex)

        for provider in self.observedSlots:
            provider.notifyRemove(bind(handleDatasetRemoval))