# Visualization handler"""TraitsUI handler for Visualization class."""fromenumimportEnum,autoimportpathlibfrommatplotlib.backends.backend_qt5aggimportFigureCanvasQTAggfromPyQt5importQtWidgets,QtGuifromtraits.trait_baseimporttraits_homefromtraitsui.apiimportHandlerfrommagmap.guiimportevent_handlersfrommagmap.ioimportclifrommagmap.settingsimportconfig_logger=config.logger.getChild(__name__)
[docs]classVisHandler(Handler):"""Custom handler for Visualization object events."""#: :class:`magmap.gui.event_handlers.FileOpenHandler`: File open event# handler to retain the object reference._file_open_handler=None
[docs]definit(self,info):"""Handle events after controls have been generated but prior to their display. Args: info (UIInfo): TraitsUI UI info. Returns: bool: True. """defhandle_tab_changed(i):# set the enum for the currently selected tab and initialize# viewers if necessarytab=ViewerTabs(i+1)# enums auto-index starting from 1info.object.selected_viewer_tab=tabprint("Changed to tab",i,tab)if(info.object.stale_viewers[tab]isStaleFlags.IMAGEortabisViewerTabs.ROI_EDandnotinfo.object.roi_edortabisViewerTabs.ATLAS_EDandnotinfo.object.atlas_edsortabisViewerTabs.MAYAVIandnotinfo.object.scene_3d_shown):# redraw if new image has not been drawn for tab, or the# corresponding viewer has not been shown beforeinfo.object.redraw_selected_viewer(clear=False)iftabisViewerTabs.MAYAVI:# initialize the camera orientationinfo.object.orient_camera()eliftabisViewerTabs.ATLAS_ED:# synchronize Atlas Editors to ROI offset if option selectedinfo.object.sync_atlas_eds_coords(check_option=True)info.object.update_imgadj_for_img()# change Trait to flag completion of controls creationinfo.object.controls_created=True# add a change listener for the viewer tab widget, which is the# first found widgettab_widgets=info.ui.control.findChildren(QtWidgets.QTabWidget)tab_widgets[0].currentChanged.connect(handle_tab_changed)# handle file open events such as Apple Events from PyInstallerapp=QtWidgets.QApplication.instance()self._file_open_handler=event_handlers.FileOpenHandler(info.object.open_image)app.installEventFilter(self._file_open_handler)# move progress bar to status barstatus_widgets=info.ui.control.findChildren(QtWidgets.QStatusBar)prog_widgets=info.ui.control.findChildren(QtWidgets.QProgressBar)ifstatus_widgetsandprog_widgets:status_widgets[0].addPermanentWidget(prog_widgets[0])# create TraitsUI preferences database if it does not existpathlib.Path(traits_home()).mkdir(parents=True,exist_ok=True)db=info.ui.get_ui_db("c")ifdbisnotNone:ifconfig.verbose:try:# show MagellanMapper related db entriesfork,vindb.items():ifk.startswith("magmap"):_logger.debug("TraitsUI preferences for %s: %s",k,v)breakexceptValueErrorase:# may give pickle protocol error in older Python versions_logger.exception(e)db.close()# WORKAROUND: TraitsUI icon does not work in Mac; use PyQt directly to# display application window icon using abs path; ignored in Windowsapp.setWindowIcon(QtGui.QIcon(str(config.ICON_PATH)))returnTrue
[docs]defclosed(self,info,is_ok):"""Shuts down the application when the GUI is closed."""cli.shutdown()
[docs]defobject_mpl_fig_active_changed(self,info):"""Change keyboard focus depending on the shown tab. TraitsUI does not hand Matplotlib figures keyboard focus except when the ``Item`` initially requests focus in ``has_focus``, and even then the figure cannot regain focus once lost. As a workaround, store the active figure in a Trait and request focus on the figure from the underlying Qt widget. Args: info (UIInfo): TraitsUI UI info. """ifinfo.object.mpl_fig_activeisNone:# into.object is the Visualization objectreturn# get all Matplotlib figure canvases displayed via TraitsUI as# Qt widgets; the control is a _StickyDialog that extends QDialogmpl_figs=info.ui.control.findChildren(FigureCanvasQTAgg)forfiginmpl_figs:iffig.figure==info.object.mpl_fig_active:# shift keyboard focus to canvas matching the currently# shown Matplotlib figurefig.setFocus()
[docs]@staticmethoddefscroll_to_bottom(eds,ed_name):"""Scroll to the bottom of the given Qt editor. Args: eds (List): Sequence of Qt editors. ed_name (str): Name of editor to scroll. """foredineds:ifed.name==ed_name:# scroll to end of text displayed.control.moveCursor(QtGui.QTextCursor.End)
[docs]defobject__roi_feedback_changed(self,info):"""Scroll to the bottom of the ROI feedback text display when the value is changed. Args: info (UIInfo): TraitsUI UI info. """self.scroll_to_bottom(info.ui._editors,"_roi_feedback")
[docs]defobject__import_feedback_changed(self,info):"""Scroll to the bottom of the import feedback text display when the value is changed. Args: info (UIInfo): TraitsUI UI info. """self.scroll_to_bottom(info.ui._editors,"_import_feedback")
[docs]defobject_select_controls_tab_changed(self,info):"""Select the given tab specified by :attr:`Visualization.select_controls_tab`. Args: info (UIInfo): TraitsUI UI info. """# the tab widget is the second found QTabWidget; subtract one since# Enums auto-increment from 1tab_widgets=info.ui.control.findChildren(QtWidgets.QTabWidget)tab_widgets[1].setCurrentIndex(info.object.select_controls_tab-1)
[docs]defobject__profiles_reset_prefs_changed(self,info):"""Reset preferences."""ifnotinfo.object._profiles_reset_prefs:return# reset window prefs stored in TraitsUI; these prefs only appear to be# stored on window close, so this reset has no impact except for# opening new windows during this sessiondb=info.ui.get_ui_db("w")ifdbisnotNone:fork,vindb.items():ifk.startswith("magmap"):deldb[k]_logger.debug("Reset TraitsUI preferences")info.object.update_status_bar_msg("Preferences were reset")breakdb.close()info.object._profiles_reset_prefs=False
[docs]classViewerTabs(Enum):"""Enumerations for viewer tabs."""ROI_ED=auto()ATLAS_ED=auto()MAYAVI=auto()
[docs]classStaleFlags(Enum):"""Enumerations for stale viewer states."""IMAGE=auto()# loaded new imageROI=auto()# changed ROI offset or size