def __init__(self, parentApplet, croppingSlots, topLevelOperatorView, drawerUiPath=None, rawInputSlot=None, crosshair=True): """ Constructor. :param croppingSlots: Provides the slots needed for sourcing/sinking crop data. See CroppingGui.CroppingSlots class source for details. :param topLevelOperatorView: is provided to the LayerViewerGui (the base class) :param drawerUiPath: can be given if you provide an extended drawer UI file. Otherwise a default one is used. :param rawInputSlot: Data from the rawInputSlot parameter will be displayed directly underneath the elements (if provided). """ # Do we have all the slots we need? assert isinstance(croppingSlots, CroppingGui.CroppingSlots) assert croppingSlots.cropInput is not None, "Missing a required slot." assert croppingSlots.cropOutput is not None, "Missing a required slot." assert croppingSlots.cropEraserValue is not None, "Missing a required slot." assert croppingSlots.cropDelete is not None, "Missing a required slot." assert croppingSlots.cropNames is not None, "Missing a required slot." assert croppingSlots.cropsAllowed is not None, "Missing a required slot." self.__cleanup_fns = [] self._croppingSlots = croppingSlots self._minCropNumber = 0 self._maxCropNumber = 99 #100 or 255 is reserved for eraser self._rawInputSlot = rawInputSlot self.topLevelOperatorView.Crops.notifyDirty(bind(self._updateCropList)) self.topLevelOperatorView.Crops.notifyDirty(bind(self._updateCropList)) self.__cleanup_fns.append( partial(self.topLevelOperatorView.Crops.unregisterDirty, bind(self._updateCropList))) self._colorTable16 = self._createDefault16ColorColorTable() self._programmaticallyRemovingCrops = False self._initCropUic(drawerUiPath) self._maxCropNumUsed = 0 self._allowDeleteLastCropOnly = False self.__initShortcuts() # Init base class super(CroppingGui, self).__init__( parentApplet, topLevelOperatorView, [croppingSlots.cropInput, croppingSlots.cropOutput], crosshair=crosshair) self._croppingSlots.cropEraserValue.setValue( self.editor.brushingModel.erasingNumber) # Register for thunk events (easy UI calls from non-GUI threads) self.thunkEventHandler = ThunkEventHandler(self)
def __init__(self, parentApplet, topLevelOperatorView): drawerUiPath = os.path.join( os.path.split(__file__)[0], 'splitBodyCarvingDrawer.ui') super(SplitBodyCarvingGui, self).__init__(parentApplet, topLevelOperatorView, drawerUiPath=drawerUiPath) self._splitInfoWidget = BodySplitInfoWidget(self, self.topLevelOperatorView) self._splitInfoWidget.navigationRequested.connect( self._handleNavigationRequest) self._labelControlUi.annotationWindowButton.pressed.connect( self._splitInfoWidget.show) # Hide all controls related to uncertainty; they aren't used in this applet self._labelControlUi.uncertaintyLabel.hide() self._labelControlUi.uncertaintyCombo.hide() self._labelControlUi.pushButtonUncertaintyFG.hide() self._labelControlUi.pushButtonUncertaintyBG.hide() # Hide manual save buttons; user must use the annotation window to save/load objects self._labelControlUi.saveControlLabel.hide() self._labelControlUi.save.hide() self._labelControlUi.saveAs.hide() self._labelControlUi.namesButton.hide() self.thunkEventHandler = ThunkEventHandler(self) fragmentColors = [ QColor(0, 0, 0, 0), # transparent (background) QColor(0, 255, 255), # cyan QColor(255, 0, 255), # magenta QColor(0, 0, 128), # navy QColor(165, 42, 42), # brown QColor(255, 105, 180), # hot pink QColor(255, 165, 0), # orange QColor(173, 255, 47), # green-yellow QColor(102, 205, 170), # dark aquamarine QColor(128, 0, 128), # purple QColor(240, 230, 140), # khaki QColor(192, 192, 192), # silver QColor(69, 69, 69) ] # dark grey self._fragmentColors = fragmentColors # In this workflow, you aren't allowed to make brushstrokes unless there is a "current fragment" def handleEditingFragmentChange(slot, *args): if slot.value == "": self._changeInteractionMode(Tool.Navigation) else: self._changeInteractionMode(Tool.Paint) self._labelControlUi.paintToolButton.setEnabled(slot.value != "") self._labelControlUi.eraserToolButton.setEnabled(slot.value != "") self._labelControlUi.labelListView.setEnabled(slot.value != "") topLevelOperatorView.CurrentEditingFragment.notifyDirty( handleEditingFragmentChange) handleEditingFragmentChange( topLevelOperatorView.CurrentEditingFragment)
def __init__(self, parentApplet, topLevelOperator): super(DataExportGui, self).__init__() self.drawer = None self.topLevelOperator = topLevelOperator self.threadRouter = ThreadRouter(self) self._thunkEventHandler = ThunkEventHandler(self) self._initAppletDrawerUic() self.initCentralUic() self.initViewerControls() self.parentApplet = parentApplet self.progressSignal = parentApplet.progressSignal self.overwrite = False @threadRoutedWithRouter(self.threadRouter) def handleNewDataset(multislot, index): # Make room in the GUI table self.batchOutputTableWidget.insertRow(index) # Update the table row data when this slot has new data # We can't bind in the row here because the row may change in the meantime. multislot[index].notifyReady(bind(self.updateTableForSlot)) if multislot[index].ready(): self.updateTableForSlot(multislot[index]) multislot[index].notifyUnready(self._updateExportButtons) multislot[index].notifyReady(self._updateExportButtons) self.topLevelOperator.ExportPath.notifyInserted(bind(handleNewDataset)) # For each dataset that already exists, update the GUI for i, subslot in enumerate(self.topLevelOperator.ExportPath): handleNewDataset(self.topLevelOperator.ExportPath, i) if subslot.ready(): self.updateTableForSlot(subslot) @threadRoutedWithRouter(self.threadRouter) def handleLaneRemoved(multislot, index, finalLength): if self.batchOutputTableWidget.rowCount() <= finalLength: return # Remove the row we don't need any more self.batchOutputTableWidget.removeRow(index) # Remove the viewer for this dataset imageMultiSlot = self.topLevelOperator.Inputs[index] if imageMultiSlot in self.layerViewerGuis.keys(): layerViewerGui = self.layerViewerGuis[imageMultiSlot] self.viewerStack.removeWidget(layerViewerGui) self._viewerControlWidgetStack.removeWidget( layerViewerGui.viewerControlWidget()) layerViewerGui.stopAndCleanUp() self.topLevelOperator.Inputs.notifyRemove(bind(handleLaneRemoved))
def __init__(self, workflow=[], parent=None, flags=QtCore.Qt.WindowFlags(0), sideSplitterSizePolicy=SideSplitterSizePolicy.Manual): QMainWindow.__init__(self, parent=parent, flags=flags) # Register for thunk events (easy UI calls from non-GUI threads) self.thunkEventHandler = ThunkEventHandler(self) self._sideSplitterSizePolicy = sideSplitterSizePolicy self.projectManager = ProjectManager() import inspect, os ilastikShellFilePath = os.path.dirname( inspect.getfile(inspect.currentframe())) uic.loadUi(ilastikShellFilePath + "/ui/ilastikShell.ui", self) self._applets = [] self.appletBarMapping = {} self.setAttribute(Qt.WA_AlwaysShowToolTips) if 'Ubuntu' in platform.platform(): # Native menus are prettier, but aren't working on Ubuntu at this time (Qt 4.7, Ubuntu 11) self.menuBar().setNativeMenuBar(False) (self._projectMenu, self._shellActions) = self._createProjectMenu() self._settingsMenu = self._createSettingsMenu() self.menuBar().addMenu(self._projectMenu) self.menuBar().addMenu(self._settingsMenu) self.updateShellProjectDisplay() self.progressDisplayManager = ProgressDisplayManager(self.statusBar) for applet in workflow: self.addApplet(applet) self.appletBar.expanded.connect(self.handleAppleBarItemExpanded) self.appletBar.clicked.connect(self.handleAppletBarClick) self.appletBar.setVerticalScrollMode(QAbstractItemView.ScrollPerPixel) # By default, make the splitter control expose a reasonable width of the applet bar self.mainSplitter.setSizes([300, 1]) self.currentAppletIndex = 0 self.currentImageIndex = -1 self.populatingImageSelectionCombo = False self.imageSelectionCombo.currentIndexChanged.connect( self.changeCurrentInputImageIndex) self.enableWorkflow = False # Global mask applied to all applets self._controlCmds = [ ] # Track the control commands that have been issued by each applet so they can be popped. self._disableCounts = [ ] # Controls for each applet can be disabled by his peers.
def __init__(self, parentApplet, labelingSlots, topLevelOperatorView, drawerUiPath=None, rawInputSlot=None, crosshair=True, is_3d_widget_visible=False): """ Constructor. :param labelingSlots: Provides the slots needed for sourcing/sinking label data. See LabelingGui.LabelingSlots class source for details. :param topLevelOperatorView: is provided to the LayerViewerGui (the base class) :param drawerUiPath: can be given if you provide an extended drawer UI file. Otherwise a default one is used. :param rawInputSlot: Data from the rawInputSlot parameter will be displayed directly underneath the elements (if provided). """ self._colorTable16 = list(colortables.default16_new) # Do have have all the slots we need? assert isinstance(labelingSlots, LabelingGui.LabelingSlots) assert labelingSlots.labelInput is not None, "Missing a required slot." assert labelingSlots.labelOutput is not None, "Missing a required slot." assert labelingSlots.labelEraserValue is not None, "Missing a required slot." assert labelingSlots.labelDelete is not None, "Missing a required slot." assert labelingSlots.labelNames is not None, "Missing a required slot." self.__cleanup_fns = [] self._labelingSlots = labelingSlots self._minLabelNumber = 0 self._maxLabelNumber = 99 #100 or 255 is reserved for eraser self._rawInputSlot = rawInputSlot self._labelingSlots.labelNames.notifyDirty(bind(self._updateLabelList)) self.__cleanup_fns.append(partial(self._labelingSlots.labelNames.unregisterDirty, bind(self._updateLabelList))) self._colorTable16 = colortables.default16_new self._programmaticallyRemovingLabels = False if drawerUiPath is None: # Default ui file drawerUiPath = os.path.split(__file__)[0] + '/labelingDrawer.ui' self._initLabelUic(drawerUiPath) # Init base class super(LabelingGui, self).__init__(parentApplet, topLevelOperatorView, [labelingSlots.labelInput, labelingSlots.labelOutput], crosshair=crosshair, is_3d_widget_visible=is_3d_widget_visible) self.__initShortcuts() self._labelingSlots.labelEraserValue.setValue(self.editor.brushingModel.erasingNumber) self._allowDeleteLastLabelOnly = False self._forceAtLeastTwoLabels = False # Register for thunk events (easy UI calls from non-GUI threads) self.thunkEventHandler = ThunkEventHandler(self) self._changeInteractionMode(Tool.Navigation)
def __init__(self, labelingSlots, topLevelOperator, drawerUiPath=None, rawInputSlot=None): """ See LabelingSlots class (above) for expected type of labelingSlots parameter. observedSlots is the same as in the LayerViewer constructor. drawerUiPath can be given if you provide an extended drawer UI file. Otherwise a default one is used. Data from the rawInputSlot parameter will be displayed directly underneatch the labels (if provided). """ # Do have have all the slots we need? assert isinstance(labelingSlots, LabelingGui.LabelingSlots) assert all([v is not None for v in labelingSlots.__dict__.values()]) self._minLabelNumber = 0 self._maxLabelNumber = 99 #100 or 255 is reserved for eraser self._rawInputSlot = rawInputSlot # Init base class super(LabelingGui, self).__init__(topLevelOperator) self._labelingSlots = labelingSlots self._labelingSlots.labelEraserValue.setValue( self.editor.brushingModel.erasingNumber) self._labelingSlots.maxLabelValue.notifyDirty( bind(self.updateLabelList)) # Register for thunk events (easy UI calls from non-GUI threads) self.thunkEventHandler = ThunkEventHandler(self) self._colorTable16 = self._createDefault16ColorColorTable() self._programmaticallyRemovingLabels = False if drawerUiPath is None: # Default ui file drawerUiPath = os.path.split(__file__)[0] + '/labelingDrawer.ui' self.initLabelUic(drawerUiPath) self.changeInteractionMode(Tool.Navigation) self.__initShortcuts()
def __init__(self, parentApplet, topLevelOperatorView): """ """ super(VigraWatershedViewerGui, self).__init__( parentApplet, topLevelOperatorView ) self.topLevelOperatorView = topLevelOperatorView op = self.topLevelOperatorView # Init padding gui updates blockPadding = PreferencesManager().get( 'vigra watershed viewer', 'block padding', 10) op.WatershedPadding.notifyDirty( self.updatePaddingGui ) op.WatershedPadding.setValue( blockPadding ) self.updatePaddingGui() # Init block shape gui updates cacheBlockShape = PreferencesManager().get( 'vigra watershed viewer', 'cache block shape', (256, 10)) op.CacheBlockShape.notifyDirty( self.updateCacheBlockGui ) op.CacheBlockShape.setValue( tuple(cacheBlockShape) ) self.updateCacheBlockGui() # Init seeds gui updates op.SeedThresholdValue.notifyDirty( self.updateSeedGui ) op.SeedThresholdValue.notifyReady( self.updateSeedGui ) op.SeedThresholdValue.notifyUnready( self.updateSeedGui ) op.MinSeedSize.notifyDirty( self.updateSeedGui ) self.updateSeedGui() # Init input channel gui updates op.InputChannelIndexes.notifyDirty( self.updateInputChannelGui ) op.InputImage.notifyMetaChanged( bind(self.updateInputChannelGui) ) self.updateInputChannelGui() self.thunkEventHandler = ThunkEventHandler(self) # Remember to unsubscribe during shutdown self.__cleanup_fns = [] self.__cleanup_fns.append( partial( op.WatershedPadding.unregisterDirty, self.updatePaddingGui ) ) self.__cleanup_fns.append( partial( op.CacheBlockShape.unregisterDirty, self.updateCacheBlockGui ) ) self.__cleanup_fns.append( partial( op.SeedThresholdValue.unregisterDirty, self.updateSeedGui ) ) self.__cleanup_fns.append( partial( op.SeedThresholdValue.unregisterReady, self.updateSeedGui ) ) self.__cleanup_fns.append( partial( op.SeedThresholdValue.unregisterUnready, self.updateSeedGui ) ) self.__cleanup_fns.append( partial( op.MinSeedSize.unregisterDirty, self.updateSeedGui ) ) self.__cleanup_fns.append( partial( op.InputChannelIndexes.unregisterDirty, self.updateInputChannelGui ) ) self.__cleanup_fns.append( partial( op.InputImage.unregisterDirty, self.updateInputChannelGui ) )
def __init__(self, topLevelOperatorView): """ """ super(VigraWatershedViewerGui, self).__init__( topLevelOperatorView ) self.topLevelOperatorView = topLevelOperatorView self.topLevelOperatorView.FreezeCache.setValue(True) self.topLevelOperatorView.OverrideLabels.setValue( { 0: (0,0,0,0) } ) # Default settings (will be overwritten by serializer) self.topLevelOperatorView.InputChannelIndexes.setValue( [] ) self.topLevelOperatorView.SeedThresholdValue.setValue( 0.0 ) self.topLevelOperatorView.MinSeedSize.setValue( 0 ) # Init padding gui updates blockPadding = PreferencesManager().get( 'vigra watershed viewer', 'block padding', 10) self.topLevelOperatorView.WatershedPadding.notifyDirty( self.updatePaddingGui ) self.topLevelOperatorView.WatershedPadding.setValue(blockPadding) self.updatePaddingGui() # Init block shape gui updates cacheBlockShape = PreferencesManager().get( 'vigra watershed viewer', 'cache block shape', (256, 10)) self.topLevelOperatorView.CacheBlockShape.notifyDirty( self.updateCacheBlockGui ) self.topLevelOperatorView.CacheBlockShape.setValue( cacheBlockShape ) self.updateCacheBlockGui() # Init seeds gui updates self.topLevelOperatorView.SeedThresholdValue.notifyDirty( self.updateSeedGui ) self.topLevelOperatorView.SeedThresholdValue.notifyReady( self.updateSeedGui ) self.topLevelOperatorView.SeedThresholdValue.notifyUnready( self.updateSeedGui ) self.topLevelOperatorView.MinSeedSize.notifyDirty( self.updateSeedGui ) self.updateSeedGui() # Init input channel gui updates self.topLevelOperatorView.InputChannelIndexes.notifyDirty( self.updateInputChannelGui ) self.topLevelOperatorView.InputChannelIndexes.setValue( [0] ) self.topLevelOperatorView.InputImage.notifyMetaChanged( bind(self.updateInputChannelGui) ) self.updateInputChannelGui() self.thunkEventHandler = ThunkEventHandler(self)