diff options
Diffstat (limited to 'silx/app/view.py')
-rw-r--r-- | silx/app/view.py | 314 |
1 files changed, 0 insertions, 314 deletions
diff --git a/silx/app/view.py b/silx/app/view.py deleted file mode 100644 index bc4e30c..0000000 --- a/silx/app/view.py +++ /dev/null @@ -1,314 +0,0 @@ -# coding: utf-8 -# /*########################################################################## -# Copyright (C) 2016-2018 European Synchrotron Radiation Facility -# -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documentation files (the "Software"), to deal -# in the Software without restriction, including without limitation the rights -# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -# copies of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in -# all copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -# THE SOFTWARE. -# -# ############################################################################*/ -"""Browse a data file with a GUI""" - -__authors__ = ["V. Valls"] -__license__ = "MIT" -__date__ = "28/02/2018" - -import sys -import os -import argparse -import logging -import collections - -_logger = logging.getLogger(__name__) -"""Module logger""" - -if "silx.gui.qt" not in sys.modules: - # Try first PyQt5 and not the priority imposed by silx.gui.qt. - # To avoid problem with unittests we only do it if silx.gui.qt is not - # yet loaded. - # TODO: Can be removed for silx 0.8, as it should be the default binding - # of the silx library. - try: - import PyQt5.QtCore - except ImportError: - pass - -from silx.gui import qt - - -class Viewer(qt.QMainWindow): - """ - This window allows to browse a data file like images or HDF5 and it's - content. - """ - - def __init__(self): - """ - :param files_: List of HDF5 or Spec files (pathes or - :class:`silx.io.spech5.SpecH5` or :class:`h5py.File` - instances) - """ - # Import it here to be sure to use the right logging level - import silx.gui.hdf5 - from silx.gui.data.DataViewerFrame import DataViewerFrame - - qt.QMainWindow.__init__(self) - self.setWindowTitle("Silx viewer") - - self.__asyncload = False - self.__dialogState = None - self.__treeview = silx.gui.hdf5.Hdf5TreeView(self) - """Silx HDF5 TreeView""" - - self.__dataViewer = DataViewerFrame(self) - vSpliter = qt.QSplitter(qt.Qt.Vertical) - vSpliter.addWidget(self.__dataViewer) - vSpliter.setSizes([10, 0]) - - spliter = qt.QSplitter(self) - spliter.addWidget(self.__treeview) - spliter.addWidget(vSpliter) - spliter.setStretchFactor(1, 1) - - main_panel = qt.QWidget(self) - layout = qt.QVBoxLayout() - layout.addWidget(spliter) - layout.setStretchFactor(spliter, 1) - main_panel.setLayout(layout) - - self.setCentralWidget(main_panel) - - model = self.__treeview.selectionModel() - model.selectionChanged.connect(self.displayData) - self.__treeview.addContextMenuCallback(self.closeAndSyncCustomContextMenu) - - treeModel = self.__treeview.findHdf5TreeModel() - columns = list(treeModel.COLUMN_IDS) - columns.remove(treeModel.DESCRIPTION_COLUMN) - columns.remove(treeModel.NODE_COLUMN) - self.__treeview.header().setSections(columns) - - self.createActions() - self.createMenus() - - def createActions(self): - action = qt.QAction("E&xit", self) - action.setShortcuts(qt.QKeySequence.Quit) - action.setStatusTip("Exit the application") - action.triggered.connect(self.close) - self._exitAction = action - - action = qt.QAction("&Open", self) - action.setStatusTip("Open a file") - action.triggered.connect(self.open) - self._openAction = action - - action = qt.QAction("&About", self) - action.setStatusTip("Show the application's About box") - action.triggered.connect(self.about) - self._aboutAction = action - - def createMenus(self): - fileMenu = self.menuBar().addMenu("&File") - fileMenu.addAction(self._openAction) - fileMenu.addSeparator() - fileMenu.addAction(self._exitAction) - helpMenu = self.menuBar().addMenu("&Help") - helpMenu.addAction(self._aboutAction) - - def open(self): - dialog = self.createFileDialog() - if self.__dialogState is None: - currentDirectory = os.getcwd() - dialog.setDirectory(currentDirectory) - else: - dialog.restoreState(self.__dialogState) - - result = dialog.exec_() - if not result: - return - - self.__dialogState = dialog.saveState() - - filenames = dialog.selectedFiles() - for filename in filenames: - self.appendFile(filename) - - def createFileDialog(self): - dialog = qt.QFileDialog(self) - dialog.setWindowTitle("Open") - dialog.setModal(True) - - # NOTE: hdf5plugin have to be loaded before - import silx.io - extensions = collections.OrderedDict() - for description, ext in silx.io.supported_extensions().items(): - extensions[description] = " ".join(sorted(list(ext))) - - # NOTE: hdf5plugin have to be loaded before - import fabio - if fabio is not None: - extensions["NeXus layout from EDF files"] = "*.edf" - extensions["NeXus layout from TIFF image files"] = "*.tif *.tiff" - extensions["NeXus layout from CBF files"] = "*.cbf" - extensions["NeXus layout from MarCCD image files"] = "*.mccd" - - all_supported_extensions = set() - for name, exts in extensions.items(): - exts = exts.split(" ") - all_supported_extensions.update(exts) - all_supported_extensions = sorted(list(all_supported_extensions)) - - filters = [] - filters.append("All supported files (%s)" % " ".join(all_supported_extensions)) - for name, extension in extensions.items(): - filters.append("%s (%s)" % (name, extension)) - filters.append("All files (*)") - - dialog.setNameFilters(filters) - dialog.setFileMode(qt.QFileDialog.ExistingFiles) - return dialog - - def about(self): - from . import qtutils - qtutils.About.about(self, "Silx viewer") - - def appendFile(self, filename): - self.__treeview.findHdf5TreeModel().appendFile(filename) - - def displayData(self): - """Called to update the dataviewer with the selected data. - """ - selected = list(self.__treeview.selectedH5Nodes(ignoreBrokenLinks=False)) - if len(selected) == 1: - # Update the viewer for a single selection - data = selected[0] - self.__dataViewer.setData(data) - - def useAsyncLoad(self, useAsync): - self.__asyncload = useAsync - - def closeAndSyncCustomContextMenu(self, event): - """Called to populate the context menu - - :param silx.gui.hdf5.Hdf5ContextMenuEvent event: Event - containing expected information to populate the context menu - """ - selectedObjects = event.source().selectedH5Nodes(ignoreBrokenLinks=False) - menu = event.menu() - - if not menu.isEmpty(): - menu.addSeparator() - - # Import it here to be sure to use the right logging level - import h5py - for obj in selectedObjects: - if obj.ntype is h5py.File: - action = qt.QAction("Remove %s" % obj.local_filename, event.source()) - action.triggered.connect(lambda: self.__treeview.findHdf5TreeModel().removeH5pyObject(obj.h5py_object)) - menu.addAction(action) - action = qt.QAction("Synchronize %s" % obj.local_filename, event.source()) - action.triggered.connect(lambda: self.__treeview.findHdf5TreeModel().synchronizeH5pyObject(obj.h5py_object)) - menu.addAction(action) - - -def main(argv): - """ - Main function to launch the viewer as an application - - :param argv: Command line arguments - :returns: exit status - """ - parser = argparse.ArgumentParser(description=__doc__) - parser.add_argument( - 'files', - nargs=argparse.ZERO_OR_MORE, - help='Data file to show (h5 file, edf files, spec files)') - parser.add_argument( - '--debug', - dest="debug", - action="store_true", - default=False, - help='Set logging system in debug mode') - parser.add_argument( - '--use-opengl-plot', - dest="use_opengl_plot", - action="store_true", - default=False, - help='Use OpenGL for plots (instead of matplotlib)') - - options = parser.parse_args(argv[1:]) - - if options.debug: - logging.root.setLevel(logging.DEBUG) - - # - # Import most of the things here to be sure to use the right logging level - # - - try: - # it should be loaded before h5py - import hdf5plugin # noqa - except ImportError: - _logger.debug("Backtrace", exc_info=True) - hdf5plugin = None - - try: - import h5py - except ImportError: - _logger.debug("Backtrace", exc_info=True) - h5py = None - - if h5py is None: - message = "Module 'h5py' is not installed but is mandatory."\ - + " You can install it using \"pip install h5py\"." - _logger.error(message) - return -1 - - if hdf5plugin is None: - message = "Module 'hdf5plugin' is not installed. It supports some hdf5"\ - + " compressions. You can install it using \"pip install hdf5plugin\"." - _logger.warning(message) - - # - # Run the application - # - - if options.use_opengl_plot: - from silx.gui.plot import PlotWidget - PlotWidget.setDefaultBackend("opengl") - - app = qt.QApplication([]) - qt.QLocale.setDefault(qt.QLocale.c()) - - sys.excepthook = qt.exceptionHandler - window = Viewer() - window.setAttribute(qt.Qt.WA_DeleteOnClose, True) - window.resize(qt.QSize(640, 480)) - - for filename in options.files: - try: - window.appendFile(filename) - except IOError as e: - _logger.error(e.args[0]) - _logger.debug("Backtrace", exc_info=True) - - window.show() - result = app.exec_() - # remove ending warnings relative to QTimer - app.deleteLater() - return result |