Beispiel #1
0
class Hdf5NodeView(CloseEventNotifyingWidget.CloseEventNotifyingWidget):
    """QWidget displaying data as raw values in a table widget, or as a
    curve, image or stack in a plot widget. It can also display information
    related to HDF5 groups (attributes, compression, ...) and interpret
    a NXdata group to plot its data.

    The plot features depend on *silx*'s availability.
    """
    def __init__(self, parent=None):
        CloseEventNotifyingWidget.CloseEventNotifyingWidget.__init__(self,
                                                                     parent)
        self.mainLayout = qt.QVBoxLayout(self)
        self.mainLayout.setContentsMargins(0, 0, 0, 0)
        self.mainLayout.setSpacing(0)

        self.viewWidget = DataViewerFrame(self)
        self.viewWidget.replaceView(DataViews.PLOT1D_MODE,
                                    Plot1DViewWithPlugins(self))
        self.viewWidget.replaceView(DataViews.PLOT2D_MODE,
                                    Plot2DViewWithPlugins(self))
        self.viewWidget.replaceView(DataViews.NXDATA_CURVE_MODE,
                                    NXdataCurveViewWithPlugins(self))
        self.viewWidget.replaceView(DataViews.NXDATA_IMAGE_MODE,
                                    NXdataImageViewWithPlugins(self))

        self.mainLayout.addWidget(self.viewWidget)

    def setData(self, dataset):
        self.viewWidget.setData(dataset)
Beispiel #2
0
    def __init__(self, file_names=None):
        qt.QWidget.__init__(self)

        self.__treeview = silx.gui.hdf5.Hdf5TreeView(self)
        self.__text = qt.QTextEdit(self)
        self.__dataViewer = DataViewerFrame(self)

        vSplitter = qt.QSplitter(qt.Qt.Vertical)
        vSplitter.addWidget(self.__dataViewer)
        vSplitter.addWidget(self.__text)
        vSplitter.setSizes([10, 0])

        splitter = qt.QSplitter(self)
        splitter.addWidget(self.__treeview)
        splitter.addWidget(vSplitter)
        splitter.setStretchFactor(1, 1)

        layout = qt.QVBoxLayout()
        layout.addWidget(splitter)
        layout.setStretchFactor(splitter, 1)
        self.setLayout(layout)

        # append all files to the tree
        if not file_names is None:
            for file_name in file_names:
                self.__treeview.findHdf5TreeModel().appendFile(file_name)

        self.__treeview.activated.connect(self.displayData)
Beispiel #3
0
    def __init__(self, filenames=None):
        """
        :param files_: List of HDF5 or Spec files (pathes or
            :class:`silx.io.spech5.SpecH5` or :class:`h5py.File`
            instances)
        """
        qt.QMainWindow.__init__(self)
        self.setWindowTitle("Silx HDF5 widget example")

        self.__asyncload = False
        self.__treeview = silx.gui.hdf5.Hdf5TreeView(self)
        """Silx HDF5 TreeView"""
        self.__text = qt.QTextEdit(self)
        """Widget displaying information"""

        self.__dataViewer = DataViewerFrame(self)
        vSpliter = qt.QSplitter(qt.Qt.Vertical)
        vSpliter.addWidget(self.__dataViewer)
        vSpliter.addWidget(self.__text)
        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.addWidget(
            self.createTreeViewConfigurationPanel(self, self.__treeview))
        layout.setStretchFactor(spliter, 1)
        main_panel.setLayout(layout)

        self.setCentralWidget(main_panel)

        # append all files to the tree
        for file_name in filenames:
            self.__treeview.findHdf5TreeModel().appendFile(file_name)

        self.__treeview.activated.connect(self.displayData)
        self.__treeview.activated.connect(
            lambda index: self.displayEvent("activated", index))
        self.__treeview.clicked.connect(
            lambda index: self.displayEvent("clicked", index))
        self.__treeview.doubleClicked.connect(
            lambda index: self.displayEvent("doubleClicked", index))
        self.__treeview.entered.connect(
            lambda index: self.displayEvent("entered", index))
        self.__treeview.pressed.connect(
            lambda index: self.displayEvent("pressed", index))

        self.__treeview.addContextMenuCallback(self.customContextMenu)
        # lambda function will never be called cause we store it as weakref
        self.__treeview.addContextMenuCallback(lambda event: None)
        # you have to store it first
        self.__store_lambda = lambda event: self.closeAndSyncCustomContextMenu(
            event)
        self.__treeview.addContextMenuCallback(self.__store_lambda)
Beispiel #4
0
class Hdf5TreeViewWidget(qt.QWidget):
    def __init__(self, file_names=None):
        qt.QWidget.__init__(self)

        self.__treeview = silx.gui.hdf5.Hdf5TreeView(self)
        self.__text = qt.QTextEdit(self)
        self.__dataViewer = DataViewerFrame(self)

        vSplitter = qt.QSplitter(qt.Qt.Vertical)
        vSplitter.addWidget(self.__dataViewer)
        vSplitter.addWidget(self.__text)
        vSplitter.setSizes([10, 0])

        splitter = qt.QSplitter(self)
        splitter.addWidget(self.__treeview)
        splitter.addWidget(vSplitter)
        splitter.setStretchFactor(1, 1)

        layout = qt.QVBoxLayout()
        layout.addWidget(splitter)
        layout.setStretchFactor(splitter, 1)
        self.setLayout(layout)

        # append all files to the tree
        if not file_names is None:
            for file_name in file_names:
                self.__treeview.findHdf5TreeModel().appendFile(file_name)

        self.__treeview.activated.connect(self.displayData)

    def displayData(self):
        """Called to update the dataviewer with the selected data.
        """
        selected = list(self.__treeview.selectedH5Nodes())
        if len(selected) == 1:
            # Update the viewer for a single selection
            data = selected[0]
            self.__dataViewer.setData(data)

    def load_file(self, filename):
        self.__treeview.findHdf5TreeModel().insertFile(filename)

    def set_text(self, text):
        self.__text.setText(text)

    def __hdf5ComboChanged(self, index):
        function = self.__hdf5Combo.itemData(index)
        self.__createHdf5Button.setCallable(function)

    def __edfComboChanged(self, index):
        function = self.__edfCombo.itemData(index)
        self.__createEdfButton.setCallable(function)
Beispiel #5
0
    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()
Beispiel #6
0
    def __init__(self, parent=None, context=None):
        qt.QWidget.__init__(self, parent=parent)

        self.__customNxdataItem = None

        self.__dataTitle = _HeaderLabel(self)
        self.__dataTitle.setVisible(False)

        self.__dataViewer = DataViewerFrame(self)
        self.__dataViewer.setGlobalHooks(context)

        layout = qt.QVBoxLayout(self)
        layout.setSpacing(0)
        layout.setContentsMargins(0, 0, 0, 0)
        layout.addWidget(self.__dataTitle)
        layout.addWidget(self.__dataViewer)
Beispiel #7
0
    def __init__(self, filenames=None):
        """
        :param files_: List of HDF5 or Spec files (pathes or
            :class:`silx.io.spech5.SpecH5` or :class:`h5py.File`
            instances)
        """
        qt.QMainWindow.__init__(self)
        self.setWindowTitle("Silx HDF5 widget example")

        self.__asyncload = False
        self.__treeview = silx.gui.hdf5.Hdf5TreeView(self)
        """Silx HDF5 TreeView"""

        self.__sourceModel = self.__treeview.model()
        """Store the source model"""

        self.__text = qt.QTextEdit(self)
        """Widget displaying information"""

        self.__dataViewer = DataViewerFrame(self)
        vSpliter = qt.QSplitter(qt.Qt.Vertical)
        vSpliter.addWidget(self.__dataViewer)
        vSpliter.addWidget(self.__text)
        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.addWidget(
            self.createTreeViewConfigurationPanel(self, self.__treeview))
        layout.setStretchFactor(spliter, 1)
        main_panel.setLayout(layout)

        self.setCentralWidget(main_panel)

        # append all files to the tree
        for file_name in filenames:
            self.__treeview.findHdf5TreeModel().appendFile(file_name)

        self.__treeview.activated.connect(self.displayData)
Beispiel #8
0
    def __init__(self, parent=None):
        CloseEventNotifyingWidget.CloseEventNotifyingWidget.__init__(self,
                                                                     parent)
        self.mainLayout = qt.QVBoxLayout(self)
        self.mainLayout.setContentsMargins(0, 0, 0, 0)
        self.mainLayout.setSpacing(0)

        self.viewWidget = DataViewerFrame(self)
        self.viewWidget.replaceView(DataViews.PLOT1D_MODE,
                                    Plot1DViewWithPlugins(self))
        self.viewWidget.replaceView(DataViews.PLOT2D_MODE,
                                    Plot2DViewWithPlugins(self))
        self.viewWidget.replaceView(DataViews.NXDATA_CURVE_MODE,
                                    NXdataCurveViewWithPlugins(self))
        self.viewWidget.replaceView(DataViews.NXDATA_IMAGE_MODE,
                                    NXdataImageViewWithPlugins(self))

        self.mainLayout.addWidget(self.viewWidget)
Beispiel #9
0
def main():
    app = qt.QApplication([])

    widget = DataViewerFrame()
    widget.addView(MyColorView(widget))
    widget.setData(Color.GREEN)
    widget.show()
    result = app.exec()
    # remove ending warnings relative to QTimer
    app.deleteLater()
    sys.exit(result)
Beispiel #10
0
    def __init__(self, filenames=None):
        """
        :param files_: List of HDF5 or Spec files (pathes or
            :class:`silx.io.spech5.SpecH5` or :class:`h5py.File`
            instances)
        """
        qt.QMainWindow.__init__(self)
        self.setWindowTitle("Silx HDF5 widget example")

        self.__asyncload = False
        self.__treeview = silx.gui.hdf5.Hdf5TreeView(self)
        """Silx HDF5 TreeView"""
        self.__text = qt.QTextEdit(self)
        """Widget displaying information"""

        self.__dataViewer = DataViewerFrame(self)
        vSpliter = qt.QSplitter(qt.Qt.Vertical)
        vSpliter.addWidget(self.__dataViewer)
        vSpliter.addWidget(self.__text)
        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.addWidget(self.createTreeViewConfigurationPanel(self, self.__treeview))
        layout.setStretchFactor(spliter, 1)
        main_panel.setLayout(layout)

        self.setCentralWidget(main_panel)

        # append all files to the tree
        for file_name in filenames:
            self.__treeview.findHdf5TreeModel().appendFile(file_name)

        self.__treeview.activated.connect(self.displayData)
        self.__treeview.activated.connect(lambda index: self.displayEvent("activated", index))
        self.__treeview.clicked.connect(lambda index: self.displayEvent("clicked", index))
        self.__treeview.doubleClicked.connect(lambda index: self.displayEvent("doubleClicked", index))
        self.__treeview.entered.connect(lambda index: self.displayEvent("entered", index))
        self.__treeview.pressed.connect(lambda index: self.displayEvent("pressed", index))

        self.__treeview.addContextMenuCallback(self.customContextMenu)
        # lambda function will never be called cause we store it as weakref
        self.__treeview.addContextMenuCallback(lambda event: None)
        # you have to store it first
        self.__store_lambda = lambda event: self.closeAndSyncCustomContextMenu(event)
        self.__treeview.addContextMenuCallback(self.__store_lambda)
Beispiel #11
0
def main():
    app = qt.QApplication([])

    widget = DataViewerFrame()
    widget.addView(MyColorView(widget))
    widget.setData(Color.GREEN)
    widget.show()
    result = app.exec_()
    # remove ending warnings relative to QTimer
    app.deleteLater()
    sys.exit(result)
    def __init__(self, file_name=None):
        qt.QWidget.__init__(self)

        self.__treeview = silx.gui.hdf5.Hdf5TreeView(self)
        self.__text = qt.QTextEdit(self)
        self.__dataViewer = DataViewerFrame(self)

        box = oasysgui.widgetBox(self, "", orientation="vertical")

        box.layout().addWidget(self.__dataViewer)
        self.box_scale = oasysgui.widgetBox(box, "", orientation="horizontal")

        gui.button(self.box_scale,
                   self,
                   "Apply Coordinates",
                   callback=self.rescale)

        vSplitter = qt.QSplitter(qt.Qt.Vertical)
        vSplitter.addWidget(box)
        vSplitter.addWidget(self.__text)
        vSplitter.setSizes([10, 0])

        splitter = qt.QSplitter(self)
        splitter.addWidget(self.__treeview)
        splitter.addWidget(vSplitter)
        splitter.setStretchFactor(1, 1)

        layout = qt.QVBoxLayout()
        layout.addWidget(splitter)
        layout.setStretchFactor(splitter, 1)
        self.setLayout(layout)

        # append all files to the tree
        if not file_name is None:
            self.__treeview.findHdf5TreeModel().removeRow(0)
            self.__treeview.findHdf5TreeModel().appendFile(file_name)

        self.__treeview.activated.connect(self.displayData)
Beispiel #13
0
    def createDefaultViews(self, parent=None):
        views = list(DataViewerFrame.createDefaultViews(self, parent=parent))

        # replace 1d view
        oldView = [v for v in views if v.modeId() == DataViews.PLOT1D_MODE][0]
        newView = Plot1DViewWithPlugins(parent=parent)
        views[views.index(oldView)] = newView

        # replace NXdataView
        oldView = [v for v in views if isinstance(v, DataViews._NXdataView)][0]
        newView = NXdataViewWithPlugins(parent=parent)
        views[views.index(oldView)] = newView

        return views
Beispiel #14
0
    def __init__(self, parent=None, context=None):
        qt.QWidget.__init__(self, parent=parent)

        self.__customNxdataItem = None

        self.__dataTitle = _HeaderLabel(self)
        self.__dataTitle.setVisible(False)

        self.__dataViewer = DataViewerFrame(self)
        self.__dataViewer.setGlobalHooks(context)

        layout = qt.QVBoxLayout(self)
        layout.setSpacing(0)
        layout.setContentsMargins(0, 0, 0, 0)
        layout.addWidget(self.__dataTitle)
        layout.addWidget(self.__dataViewer)
Beispiel #15
0
    def __init__(self, parent=None):
        CloseEventNotifyingWidget.CloseEventNotifyingWidget.__init__(
            self, parent)
        self.mainLayout = qt.QVBoxLayout(self)
        self.mainLayout.setContentsMargins(0, 0, 0, 0)
        self.mainLayout.setSpacing(0)

        if silx.hexversion >= 0x000700f0:  # 0.7.0 final
            self.viewWidget = DataViewerFrame(self)
            self.viewWidget.replaceView(DataViews.PLOT1D_MODE,
                                        Plot1DViewWithPlugins(self))
            self.viewWidget.replaceView(DataViews.NXDATA_CURVE_MODE,
                                        NXdataCurveViewWithPlugins(self))
        else:
            self.viewWidget = DataViewerFrameWithPlugins(self)

        self.mainLayout.addWidget(self.viewWidget)
Beispiel #16
0
    def __init__(self, filenames=None):
        """
        :param files_: List of HDF5 or Spec files (pathes or
            :class:`silx.io.spech5.SpecH5` or :class:`h5py.File`
            instances)
        """
        qt.QMainWindow.__init__(self)
        self.setWindowTitle("Silx HDF5 widget example")

        self.__asyncload = False
        self.__treeview = silx.gui.hdf5.Hdf5TreeView(self)
        """Silx HDF5 TreeView"""

        self.__sourceModel = self.__treeview.model()
        """Store the source model"""

        self.__text = qt.QTextEdit(self)
        """Widget displaying information"""

        self.__dataViewer = DataViewerFrame(self)
        vSpliter = qt.QSplitter(qt.Qt.Vertical)
        vSpliter.addWidget(self.__dataViewer)
        vSpliter.addWidget(self.__text)
        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.addWidget(self.createTreeViewConfigurationPanel(self, self.__treeview))
        layout.setStretchFactor(spliter, 1)
        main_panel.setLayout(layout)

        self.setCentralWidget(main_panel)

        # append all files to the tree
        for file_name in filenames:
            self.__treeview.findHdf5TreeModel().appendFile(file_name)

        self.__treeview.activated.connect(self.displayData)
Beispiel #17
0
class Hdf5TreeViewExample(qt.QMainWindow):
    """
    This window show an example of use of a Hdf5TreeView.

    The tree is initialized with a list of filenames. A panel allow to play
    with internal property configuration of the widget, and a text screen
    allow to display events.
    """

    def __init__(self, filenames=None):
        """
        :param files_: List of HDF5 or Spec files (pathes or
            :class:`silx.io.spech5.SpecH5` or :class:`h5py.File`
            instances)
        """
        qt.QMainWindow.__init__(self)
        self.setWindowTitle("Silx HDF5 widget example")

        self.__asyncload = False
        self.__treeview = silx.gui.hdf5.Hdf5TreeView(self)
        """Silx HDF5 TreeView"""

        self.__sourceModel = self.__treeview.model()
        """Store the source model"""

        self.__text = qt.QTextEdit(self)
        """Widget displaying information"""

        self.__dataViewer = DataViewerFrame(self)
        vSpliter = qt.QSplitter(qt.Qt.Vertical)
        vSpliter.addWidget(self.__dataViewer)
        vSpliter.addWidget(self.__text)
        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.addWidget(self.createTreeViewConfigurationPanel(self, self.__treeview))
        layout.setStretchFactor(spliter, 1)
        main_panel.setLayout(layout)

        self.setCentralWidget(main_panel)

        # append all files to the tree
        for file_name in filenames:
            self.__treeview.findHdf5TreeModel().appendFile(file_name)

        self.__treeview.activated.connect(self.displayData)

    def displayData(self):
        """Called to update the dataviewer with the selected data.
        """
        selected = list(self.__treeview.selectedH5Nodes())
        if len(selected) == 1:
            # Update the viewer for a single selection
            data = selected[0]
            # data is a hdf5.H5Node object
            # data.h5py_object is a Group/Dataset object (from h5py, spech5, fabioh5)
            # The dataviewer can display both
            self.__dataViewer.setData(data)

    def __fileCreated(self, filename):
        if self.__asyncload:
            self.__treeview.findHdf5TreeModel().insertFileAsync(filename)
        else:
            self.__treeview.findHdf5TreeModel().insertFile(filename)

    def __hdf5ComboChanged(self, index):
        function = self.__hdf5Combo.itemData(index)
        self.__createHdf5Button.setCallable(function)

    def __edfComboChanged(self, index):
        function = self.__edfCombo.itemData(index)
        self.__createEdfButton.setCallable(function)

    def __useCustomLabel(self):
        customModel = CustomTooltips(self.__treeview)
        customModel.setSourceModel(self.__sourceModel)
        self.__treeview.setModel(customModel)

    def __useOriginalModel(self):
        self.__treeview.setModel(self.__sourceModel)

    def createTreeViewConfigurationPanel(self, parent, treeview):
        """Create a configuration panel to allow to play with widget states"""
        panel = qt.QWidget(parent)
        panel.setLayout(qt.QHBoxLayout())

        content = qt.QGroupBox("Create HDF5", panel)
        content.setLayout(qt.QVBoxLayout())
        panel.layout().addWidget(content)

        combo = qt.QComboBox()
        combo.addItem("Containing all types", get_hdf5_with_all_types)
        combo.activated.connect(self.__hdf5ComboChanged)
        content.layout().addWidget(combo)

        button = ThreadPoolPushButton(content, text="Create")
        button.setCallable(combo.itemData(combo.currentIndex()))
        button.succeeded.connect(self.__fileCreated)
        content.layout().addWidget(button)

        self.__hdf5Combo = combo
        self.__createHdf5Button = button

        content.layout().addStretch(1)

        option = qt.QGroupBox("Custom model", panel)
        option.setLayout(qt.QVBoxLayout())
        panel.layout().addWidget(option)

        button = qt.QPushButton("Original model")
        button.clicked.connect(self.__useOriginalModel)
        option.layout().addWidget(button)

        button = qt.QPushButton("Custom tooltips by composition")
        button.clicked.connect(self.__useCustomLabel)
        option.layout().addWidget(button)

        option.layout().addStretch(1)

        panel.layout().addStretch(1)
        return panel
class Hdf5TreeViewWidget(qt.QWidget):
    x_scale = None
    y_scale = None

    def __init__(self, file_name=None):
        qt.QWidget.__init__(self)

        self.__treeview = silx.gui.hdf5.Hdf5TreeView(self)
        self.__text = qt.QTextEdit(self)
        self.__dataViewer = DataViewerFrame(self)

        box = oasysgui.widgetBox(self, "", orientation="vertical")

        box.layout().addWidget(self.__dataViewer)
        self.box_scale = oasysgui.widgetBox(box, "", orientation="horizontal")

        gui.button(self.box_scale,
                   self,
                   "Apply Coordinates",
                   callback=self.rescale)

        vSplitter = qt.QSplitter(qt.Qt.Vertical)
        vSplitter.addWidget(box)
        vSplitter.addWidget(self.__text)
        vSplitter.setSizes([10, 0])

        splitter = qt.QSplitter(self)
        splitter.addWidget(self.__treeview)
        splitter.addWidget(vSplitter)
        splitter.setStretchFactor(1, 1)

        layout = qt.QVBoxLayout()
        layout.addWidget(splitter)
        layout.setStretchFactor(splitter, 1)
        self.setLayout(layout)

        # append all files to the tree
        if not file_name is None:
            self.__treeview.findHdf5TreeModel().removeRow(0)
            self.__treeview.findHdf5TreeModel().appendFile(file_name)

        self.__treeview.activated.connect(self.displayData)

    def displayData(self):
        """Called to update the dataviewer with the selected data.
        """
        selected = list(self.__treeview.selectedH5Nodes())
        if len(selected) == 1:
            data = selected[0]
            self.__dataViewer.setData(data)

            self.is_histogram_v = "histogram_v" in data.h5py_object.name
            self.object_name = data.basename

            file = data.h5py_object.file

            try:
                self.x_scale = file["coordinates/X"].value
                self.x_label = file["coordinates"].attrs["x_label"]
                try:
                    self.y_scale = file["coordinates/Y"].value
                    self.y_label = file["coordinates"].attrs["y_label"]
                except:
                    self.y_scale = None
                    self.y_label = None

                self.box_scale.setVisible(True)
            except:
                self.box_scale.setVisible(False)

    def rescale(self):
        current_view = self.__dataViewer.displayedView()
        if isinstance(current_view, DataViews._Plot1dView):
            if self.is_histogram_v:
                min_x = numpy.min(self.y_scale)
                max_x = numpy.max(self.y_scale)
                scale = self.y_scale
                label = self.y_label
            else:
                min_x = numpy.min(self.x_scale)
                max_x = numpy.max(self.x_scale)
                scale = self.x_scale
                label = self.x_label

            widget = current_view.getWidget()

            if isinstance(widget, Plot1D):
                curve = widget.getAllCurves()[0]
                curve.setData(scale, curve.getYData())
                widget.setGraphXLimits(min_x, max_x)
                widget.setGraphXLabel(label)
                widget.setGraphYLabel(self.object_name)

        elif isinstance(current_view, DataViews._ImageView):
            min_x = numpy.min(self.x_scale)
            max_x = numpy.max(self.x_scale)
            nbins_x = len(self.x_scale)
            min_y = numpy.min(self.y_scale)
            max_y = numpy.max(self.y_scale)
            nbins_y = len(self.y_scale)

            origin = (min_x, min_y)
            scale = (abs(
                (max_x - min_x) / nbins_x), abs((max_y - min_y) / nbins_y))

            for view in current_view.availableViews():
                widget = view.getWidget()

                if isinstance(widget, Plot2D):
                    widget.getActiveImage().setOrigin(origin)
                    widget.getActiveImage().setScale(scale)
                    widget.setGraphXLimits(min_x, max_x)
                    widget.setGraphYLimits(min_y, max_y)
                    widget.setGraphXLabel(self.x_label)
                    widget.setGraphYLabel(self.y_label)
                    widget.setKeepDataAspectRatio(False)
                    widget.resetZoom()

    def load_file(self, filename):
        self.__treeview.findHdf5TreeModel().insertFile(filename)

    def set_text(self, text):
        self.__text.setText(text)

    def __hdf5ComboChanged(self, index):
        function = self.__hdf5Combo.itemData(index)
        self.__createHdf5Button.setCallable(function)

    def __edfComboChanged(self, index):
        function = self.__edfCombo.itemData(index)
        self.__createEdfButton.setCallable(function)
Beispiel #19
0
class Hdf5TreeViewExample(qt.QMainWindow):
    """
    This window show an example of use of a Hdf5TreeView.

    The tree is initialized with a list of filenames. A panel allow to play
    with internal property configuration of the widget, and a text screen
    allow to display events.
    """
    def __init__(self, filenames=None):
        """
        :param files_: List of HDF5 or Spec files (pathes or
            :class:`silx.io.spech5.SpecH5` or :class:`h5py.File`
            instances)
        """
        qt.QMainWindow.__init__(self)
        self.setWindowTitle("Silx HDF5 widget example")

        self.__asyncload = False
        self.__treeview = silx.gui.hdf5.Hdf5TreeView(self)
        """Silx HDF5 TreeView"""
        self.__text = qt.QTextEdit(self)
        """Widget displaying information"""

        self.__dataViewer = DataViewerFrame(self)
        vSpliter = qt.QSplitter(qt.Qt.Vertical)
        vSpliter.addWidget(self.__dataViewer)
        vSpliter.addWidget(self.__text)
        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.addWidget(
            self.createTreeViewConfigurationPanel(self, self.__treeview))
        layout.setStretchFactor(spliter, 1)
        main_panel.setLayout(layout)

        self.setCentralWidget(main_panel)

        # append all files to the tree
        for file_name in filenames:
            self.__treeview.findHdf5TreeModel().appendFile(file_name)

        self.__treeview.activated.connect(self.displayData)
        self.__treeview.activated.connect(
            lambda index: self.displayEvent("activated", index))
        self.__treeview.clicked.connect(
            lambda index: self.displayEvent("clicked", index))
        self.__treeview.doubleClicked.connect(
            lambda index: self.displayEvent("doubleClicked", index))
        self.__treeview.entered.connect(
            lambda index: self.displayEvent("entered", index))
        self.__treeview.pressed.connect(
            lambda index: self.displayEvent("pressed", index))

        self.__treeview.addContextMenuCallback(self.customContextMenu)
        # lambda function will never be called cause we store it as weakref
        self.__treeview.addContextMenuCallback(lambda event: None)
        # you have to store it first
        self.__store_lambda = lambda event: self.closeAndSyncCustomContextMenu(
            event)
        self.__treeview.addContextMenuCallback(self.__store_lambda)

    def displayData(self):
        """Called to update the dataviewer with the selected data.
        """
        selected = list(self.__treeview.selectedH5Nodes())
        if len(selected) == 1:
            # Update the viewer for a single selection
            data = selected[0]
            # data is a hdf5.H5Node object
            # data.h5py_object is a Group/Dataset object (from h5py, spech5, fabioh5)
            # The dataviewer can display both
            self.__dataViewer.setData(data)

    def displayEvent(self, eventName, index):
        """Called to log event in widget
        """
        def formatKey(name, value):
            name, value = html.escape(str(name)), html.escape(str(value))
            return "<li><b>%s</b>: %s</li>" % (name, value)

        text = "<html>"
        text += "<h1>Event</h1>"
        text += "<ul>"
        text += formatKey("name", eventName)
        text += formatKey("index", type(index))
        text += "</ul>"

        text += "<h1>Selected HDF5 objects</h1>"

        for h5_obj in self.__treeview.selectedH5Nodes():
            text += "<h2>HDF5 object</h2>"
            text += "<ul>"
            text += formatKey("local_filename", h5_obj.local_file.filename)
            text += formatKey("local_basename", h5_obj.local_basename)
            text += formatKey("local_name", h5_obj.local_name)
            text += formatKey("real_filename", h5_obj.file.filename)
            text += formatKey("real_basename", h5_obj.basename)
            text += formatKey("real_name", h5_obj.name)

            text += formatKey("obj", h5_obj.ntype)
            text += formatKey("dtype", getattr(h5_obj, "dtype", None))
            text += formatKey("shape", getattr(h5_obj, "shape", None))
            text += formatKey("attrs", getattr(h5_obj, "attrs", None))
            if hasattr(h5_obj, "attrs"):
                text += "<ul>"
                if len(h5_obj.attrs) == 0:
                    text += "<li>empty</li>"
                for key, value in h5_obj.attrs.items():
                    text += formatKey(key, value)
                text += "</ul>"
            text += "</ul>"

        text += "</html>"
        self.__text.setHtml(text)

    def useAsyncLoad(self, useAsync):
        self.__asyncload = useAsync

    def __fileCreated(self, filename):
        if self.__asyncload:
            self.__treeview.findHdf5TreeModel().insertFileAsync(filename)
        else:
            self.__treeview.findHdf5TreeModel().insertFile(filename)

    def customContextMenu(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()
        menu = event.menu()

        hasDataset = False
        for obj in selectedObjects:
            if obj.ntype is h5py.Dataset:
                hasDataset = True
                break

        if not menu.isEmpty():
            menu.addSeparator()

        if hasDataset:
            action = qt.QAction("Do something on the datasets", event.source())
            menu.addAction(action)

    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()
        menu = event.menu()

        if not menu.isEmpty():
            menu.addSeparator()

        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 __hdf5ComboChanged(self, index):
        function = self.__hdf5Combo.itemData(index)
        self.__createHdf5Button.setCallable(function)

    def __edfComboChanged(self, index):
        function = self.__edfCombo.itemData(index)
        self.__createEdfButton.setCallable(function)

    def createTreeViewConfigurationPanel(self, parent, treeview):
        """Create a configuration panel to allow to play with widget states"""
        panel = qt.QWidget(parent)
        panel.setLayout(qt.QHBoxLayout())

        content = qt.QGroupBox("Create HDF5", panel)
        content.setLayout(qt.QVBoxLayout())
        panel.layout().addWidget(content)

        combo = qt.QComboBox()
        combo.addItem("Containing all types", get_hdf5_with_all_types)
        combo.addItem("Containing all links", get_hdf5_with_all_links)
        combo.addItem("Containing 1000 datasets", get_hdf5_with_1000_datasets)
        combo.addItem("Containing 10000 datasets",
                      get_hdf5_with_10000_datasets)
        combo.addItem("Containing 100000 datasets",
                      get_hdf5_with_100000_datasets)
        combo.addItem("Containing recursive links",
                      get_hdf5_with_recursive_links)
        combo.addItem("Containing external recursive links",
                      get_hdf5_with_external_recursive_links)
        combo.addItem("Containing NXdata groups", get_hdf5_with_nxdata)
        combo.activated.connect(self.__hdf5ComboChanged)
        content.layout().addWidget(combo)

        button = ThreadPoolPushButton(content, text="Create")
        button.setCallable(combo.itemData(combo.currentIndex()))
        button.succeeded.connect(self.__fileCreated)
        content.layout().addWidget(button)

        self.__hdf5Combo = combo
        self.__createHdf5Button = button

        asyncload = qt.QCheckBox("Async load", content)
        asyncload.setChecked(self.__asyncload)
        asyncload.toggled.connect(
            lambda: self.useAsyncLoad(asyncload.isChecked()))
        content.layout().addWidget(asyncload)

        content.layout().addStretch(1)

        content = qt.QGroupBox("Create EDF", panel)
        content.setLayout(qt.QVBoxLayout())
        panel.layout().addWidget(content)

        combo = qt.QComboBox()
        combo.addItem("Containing all types", get_edf_with_all_types)
        combo.addItem("Containing 100000 datasets", get_edf_with_100000_frames)
        combo.activated.connect(self.__edfComboChanged)
        content.layout().addWidget(combo)

        button = ThreadPoolPushButton(content, text="Create")
        button.setCallable(combo.itemData(combo.currentIndex()))
        button.succeeded.connect(self.__fileCreated)
        content.layout().addWidget(button)

        self.__edfCombo = combo
        self.__createEdfButton = button

        content.layout().addStretch(1)

        option = qt.QGroupBox("Tree options", panel)
        option.setLayout(qt.QVBoxLayout())
        panel.layout().addWidget(option)

        sorting = qt.QCheckBox("Enable sorting", option)
        sorting.setChecked(
            treeview.selectionMode() == qt.QAbstractItemView.MultiSelection)
        sorting.toggled.connect(
            lambda: treeview.setSortingEnabled(sorting.isChecked()))
        option.layout().addWidget(sorting)

        multiselection = qt.QCheckBox("Multi-selection", option)
        multiselection.setChecked(
            treeview.selectionMode() == qt.QAbstractItemView.MultiSelection)
        switch_selection = lambda: treeview.setSelectionMode(
            qt.QAbstractItemView.MultiSelection if multiselection.isChecked(
            ) else qt.QAbstractItemView.SingleSelection)
        multiselection.toggled.connect(switch_selection)
        option.layout().addWidget(multiselection)

        filedrop = qt.QCheckBox("Drop external file", option)
        filedrop.setChecked(treeview.findHdf5TreeModel().isFileDropEnabled())
        filedrop.toggled.connect(lambda: treeview.findHdf5TreeModel().
                                 setFileDropEnabled(filedrop.isChecked()))
        option.layout().addWidget(filedrop)

        filemove = qt.QCheckBox("Reorder files", option)
        filemove.setChecked(treeview.findHdf5TreeModel().isFileMoveEnabled())
        filemove.toggled.connect(lambda: treeview.findHdf5TreeModel().
                                 setFileMoveEnabled(filedrop.isChecked()))
        option.layout().addWidget(filemove)

        option.layout().addStretch(1)

        option = qt.QGroupBox("Header options", panel)
        option.setLayout(qt.QVBoxLayout())
        panel.layout().addWidget(option)

        autosize = qt.QCheckBox("Auto-size headers", option)
        autosize.setChecked(treeview.header().hasAutoResizeColumns())
        autosize.toggled.connect(lambda: treeview.header().
                                 setAutoResizeColumns(autosize.isChecked()))
        option.layout().addWidget(autosize)

        columnpopup = qt.QCheckBox("Popup to hide/show columns", option)
        columnpopup.setChecked(treeview.header().hasHideColumnsPopup())
        columnpopup.toggled.connect(lambda: treeview.header(
        ).setEnableHideColumnsPopup(columnpopup.isChecked()))
        option.layout().addWidget(columnpopup)

        define_columns = qt.QComboBox()
        define_columns.addItem("Default columns",
                               treeview.findHdf5TreeModel().COLUMN_IDS)
        define_columns.addItem("Only name and Value", [
            treeview.findHdf5TreeModel().NAME_COLUMN,
            treeview.findHdf5TreeModel().VALUE_COLUMN
        ])
        define_columns.activated.connect(lambda index: treeview.header(
        ).setSections(define_columns.itemData(index)))
        option.layout().addWidget(define_columns)

        option.layout().addStretch(1)

        panel.layout().addStretch(1)

        return panel
Beispiel #20
0
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 create_widget(self):
     return DataViewerFrame()
Beispiel #22
0
class Hdf5TreeViewExample(qt.QMainWindow):
    """
    This window show an example of use of a Hdf5TreeView.

    The tree is initialized with a list of filenames. A panel allow to play
    with internal property configuration of the widget, and a text screen
    allow to display events.
    """
    def __init__(self, filenames=None):
        """
        :param files_: List of HDF5 or Spec files (pathes or
            :class:`silx.io.spech5.SpecH5` or :class:`h5py.File`
            instances)
        """
        qt.QMainWindow.__init__(self)
        self.setWindowTitle("Silx HDF5 widget example")

        self.__asyncload = False
        self.__treeview = silx.gui.hdf5.Hdf5TreeView(self)
        """Silx HDF5 TreeView"""

        self.__sourceModel = self.__treeview.model()
        """Store the source model"""

        self.__text = qt.QTextEdit(self)
        """Widget displaying information"""

        self.__dataViewer = DataViewerFrame(self)
        vSpliter = qt.QSplitter(qt.Qt.Vertical)
        vSpliter.addWidget(self.__dataViewer)
        vSpliter.addWidget(self.__text)
        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.addWidget(
            self.createTreeViewConfigurationPanel(self, self.__treeview))
        layout.setStretchFactor(spliter, 1)
        main_panel.setLayout(layout)

        self.setCentralWidget(main_panel)

        # append all files to the tree
        for file_name in filenames:
            self.__treeview.findHdf5TreeModel().appendFile(file_name)

        self.__treeview.activated.connect(self.displayData)

    def displayData(self):
        """Called to update the dataviewer with the selected data.
        """
        selected = list(self.__treeview.selectedH5Nodes())
        if len(selected) == 1:
            # Update the viewer for a single selection
            data = selected[0]
            # data is a hdf5.H5Node object
            # data.h5py_object is a Group/Dataset object (from h5py, spech5, fabioh5)
            # The dataviewer can display both
            self.__dataViewer.setData(data)

    def __fileCreated(self, filename):
        if self.__asyncload:
            self.__treeview.findHdf5TreeModel().insertFileAsync(filename)
        else:
            self.__treeview.findHdf5TreeModel().insertFile(filename)

    def __hdf5ComboChanged(self, index):
        function = self.__hdf5Combo.itemData(index)
        self.__createHdf5Button.setCallable(function)

    def __edfComboChanged(self, index):
        function = self.__edfCombo.itemData(index)
        self.__createEdfButton.setCallable(function)

    def __useCustomLabel(self):
        customModel = CustomTooltips(self.__treeview)
        customModel.setSourceModel(self.__sourceModel)
        self.__treeview.setModel(customModel)

    def __useOriginalModel(self):
        self.__treeview.setModel(self.__sourceModel)

    def createTreeViewConfigurationPanel(self, parent, treeview):
        """Create a configuration panel to allow to play with widget states"""
        panel = qt.QWidget(parent)
        panel.setLayout(qt.QHBoxLayout())

        content = qt.QGroupBox("Create HDF5", panel)
        content.setLayout(qt.QVBoxLayout())
        panel.layout().addWidget(content)

        combo = qt.QComboBox()
        combo.addItem("Containing all types", get_hdf5_with_all_types)
        combo.activated.connect(self.__hdf5ComboChanged)
        content.layout().addWidget(combo)

        button = ThreadPoolPushButton(content, text="Create")
        button.setCallable(combo.itemData(combo.currentIndex()))
        button.succeeded.connect(self.__fileCreated)
        content.layout().addWidget(button)

        self.__hdf5Combo = combo
        self.__createHdf5Button = button

        content.layout().addStretch(1)

        option = qt.QGroupBox("Custom model", panel)
        option.setLayout(qt.QVBoxLayout())
        panel.layout().addWidget(option)

        button = qt.QPushButton("Original model")
        button.clicked.connect(self.__useOriginalModel)
        option.layout().addWidget(button)

        button = qt.QPushButton("Custom tooltips by composition")
        button.clicked.connect(self.__useCustomLabel)
        option.layout().addWidget(button)

        option.layout().addStretch(1)

        panel.layout().addStretch(1)
        return panel
Beispiel #23
0
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.__context = ApplicationContext(self)
        self.__context.restoreLibrarySettings()

        self.__asyncload = False
        self.__dialogState = None
        self.__treeview = silx.gui.hdf5.Hdf5TreeView(self)
        """Silx HDF5 TreeView"""

        # Custom the model to be able to manage the life cycle of the files
        treeModel = silx.gui.hdf5.Hdf5TreeModel(self.__treeview,
                                                ownFiles=False)
        treeModel.sigH5pyObjectLoaded.connect(self.__h5FileLoaded)
        treeModel.sigH5pyObjectRemoved.connect(self.__h5FileRemoved)
        treeModel.sigH5pyObjectSynchronized.connect(self.__h5FileSynchonized)
        treeModel2 = silx.gui.hdf5.NexusSortFilterProxyModel(self.__treeview)
        treeModel2.setSourceModel(treeModel)
        self.__treeview.setModel(treeModel2)

        self.__dataViewer = DataViewerFrame(self)
        self.__dataViewer.setGlobalHooks(self.__context)
        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)
        self.__spliter = spliter

        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._iconUpward = icons.getQIcon('plot-yup')
        self._iconDownward = icons.getQIcon('plot-ydown')

        self.createActions()
        self.createMenus()
        self.__context.restoreSettings()

    def __h5FileLoaded(self, loadedH5):
        self.__context.pushRecentFile(loadedH5.file.filename)

    def __h5FileRemoved(self, removedH5):
        data = self.__dataViewer.data()
        if data is not None:
            if data.file.filename == removedH5.file.filename:
                self.__dataViewer.setData(None)
        removedH5.close()

    def __h5FileSynchonized(self, removedH5, loadedH5):
        data = self.__dataViewer.data()
        if data is not None:
            if data.file.filename == removedH5.file.filename:
                # Try to synchonize the viewed data
                try:
                    # TODO: It have to update the data without changing the view
                    # which is not so easy
                    newData = loadedH5[data.name]
                    self.__dataViewer.setData(newData)
                except Exception:
                    _logger.debug("Backtrace", exc_info=True)
        removedH5.close()

    def closeEvent(self, event):
        self.__context.saveSettings()

    def saveSettings(self, settings):
        """Save the window settings to this settings object

        :param qt.QSettings settings: Initialized settings
        """
        isFullScreen = bool(self.windowState() & qt.Qt.WindowFullScreen)
        if isFullScreen:
            # show in normal to catch the normal geometry
            self.showNormal()

        settings.beginGroup("mainwindow")
        settings.setValue("size", self.size())
        settings.setValue("pos", self.pos())
        settings.setValue("full-screen", isFullScreen)
        settings.endGroup()

        settings.beginGroup("mainlayout")
        settings.setValue("spliter", self.__spliter.sizes())
        settings.endGroup()

        if isFullScreen:
            self.showFullScreen()

    def restoreSettings(self, settings):
        """Restore the window settings using this settings object

        :param qt.QSettings settings: Initialized settings
        """
        settings.beginGroup("mainwindow")
        size = settings.value("size", qt.QSize(640, 480))
        pos = settings.value("pos", qt.QPoint())
        isFullScreen = settings.value("full-screen", False)
        if not isinstance(isFullScreen, bool):
            isFullScreen = False
        settings.endGroup()

        settings.beginGroup("mainlayout")
        try:
            data = settings.value("spliter")
            data = [int(d) for d in data]
            self.__spliter.setSizes(data)
        except Exception:
            _logger.debug("Backtrace", exc_info=True)
        settings.endGroup()

        if not pos.isNull():
            self.move(pos)
        if not size.isNull():
            self.resize(size)
        if isFullScreen:
            self.showFullScreen()

    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("Open Recent", self)
        action.setStatusTip("Open a recently openned file")
        action.triggered.connect(self.open)
        self._openRecentAction = action

        action = qt.QAction("&About", self)
        action.setStatusTip("Show the application's About box")
        action.triggered.connect(self.about)
        self._aboutAction = action

        # Plot backend

        action = qt.QAction("Plot rendering backend", self)
        action.setStatusTip("Select plot rendering backend")
        self._plotBackendSelection = action

        menu = qt.QMenu()
        action.setMenu(menu)
        group = qt.QActionGroup(self)
        group.setExclusive(True)

        action = qt.QAction("matplotlib", self)
        action.setStatusTip("Plot will be rendered using matplotlib")
        action.setCheckable(True)
        action.triggered.connect(self.__forceMatplotlibBackend)
        group.addAction(action)
        menu.addAction(action)
        self._usePlotWithMatplotlib = action

        action = qt.QAction("OpenGL", self)
        action.setStatusTip("Plot will be rendered using OpenGL")
        action.setCheckable(True)
        action.triggered.connect(self.__forceOpenglBackend)
        group.addAction(action)
        menu.addAction(action)
        self._usePlotWithOpengl = action

        # Plot image orientation

        action = qt.QAction("Default plot image y-axis orientation", self)
        action.setStatusTip(
            "Select the default y-axis orientation used by plot displaying images"
        )
        self._plotImageOrientation = action

        menu = qt.QMenu()
        action.setMenu(menu)
        group = qt.QActionGroup(self)
        group.setExclusive(True)

        action = qt.QAction("Downward, origin on top", self)
        action.setIcon(self._iconDownward)
        action.setStatusTip(
            "Plot images will use a downward Y-axis orientation")
        action.setCheckable(True)
        action.triggered.connect(self.__forcePlotImageDownward)
        group.addAction(action)
        menu.addAction(action)
        self._useYAxisOrientationDownward = action

        action = qt.QAction("Upward, origin on bottom", self)
        action.setIcon(self._iconUpward)
        action.setStatusTip("Plot images will use a upward Y-axis orientation")
        action.setCheckable(True)
        action.triggered.connect(self.__forcePlotImageUpward)
        group.addAction(action)
        menu.addAction(action)
        self._useYAxisOrientationUpward = action

    def __updateFileMenu(self):
        files = self.__context.getRecentFiles()
        self._openRecentAction.setEnabled(len(files) != 0)
        menu = None
        if len(files) != 0:
            menu = qt.QMenu()
            for filePath in files:
                baseName = os.path.basename(filePath)
                action = qt.QAction(baseName, self)
                action.setToolTip(filePath)
                action.triggered.connect(
                    functools.partial(self.__openRecentFile, filePath))
                menu.addAction(action)
            menu.addSeparator()
            baseName = os.path.basename(filePath)
            action = qt.QAction("Clear history", self)
            action.setToolTip("Clear the history of the recent files")
            action.triggered.connect(self.__clearRecentFile)
            menu.addAction(action)
        self._openRecentAction.setMenu(menu)

    def __clearRecentFile(self):
        self.__context.clearRencentFiles()

    def __openRecentFile(self, filePath):
        self.appendFile(filePath)

    def __updateOptionMenu(self):
        """Update the state of the checked options as it is based on global
        environment values."""

        # plot backend

        action = self._plotBackendSelection
        title = action.text().split(": ", 1)[0]
        action.setText("%s: %s" % (title, silx.config.DEFAULT_PLOT_BACKEND))

        action = self._usePlotWithMatplotlib
        action.setChecked(
            silx.config.DEFAULT_PLOT_BACKEND in ["matplotlib", "mpl"])
        title = action.text().split(" (", 1)[0]
        if not action.isChecked():
            title += " (applied after application restart)"
        action.setText(title)

        action = self._usePlotWithOpengl
        action.setChecked(silx.config.DEFAULT_PLOT_BACKEND in ["opengl", "gl"])
        title = action.text().split(" (", 1)[0]
        if not action.isChecked():
            title += " (applied after application restart)"
        action.setText(title)

        # plot orientation

        action = self._plotImageOrientation
        if silx.config.DEFAULT_PLOT_IMAGE_Y_AXIS_ORIENTATION == "downward":
            action.setIcon(self._iconDownward)
        else:
            action.setIcon(self._iconUpward)
        action.setIconVisibleInMenu(True)

        action = self._useYAxisOrientationDownward
        action.setChecked(
            silx.config.DEFAULT_PLOT_IMAGE_Y_AXIS_ORIENTATION == "downward")
        title = action.text().split(" (", 1)[0]
        if not action.isChecked():
            title += " (applied after application restart)"
        action.setText(title)

        action = self._useYAxisOrientationUpward
        action.setChecked(
            silx.config.DEFAULT_PLOT_IMAGE_Y_AXIS_ORIENTATION != "downward")
        title = action.text().split(" (", 1)[0]
        if not action.isChecked():
            title += " (applied after application restart)"
        action.setText(title)

    def createMenus(self):
        fileMenu = self.menuBar().addMenu("&File")
        fileMenu.addAction(self._openAction)
        fileMenu.addAction(self._openRecentAction)
        fileMenu.addSeparator()
        fileMenu.addAction(self._exitAction)
        fileMenu.aboutToShow.connect(self.__updateFileMenu)

        optionMenu = self.menuBar().addMenu("&Options")
        optionMenu.addAction(self._plotImageOrientation)
        optionMenu.addAction(self._plotBackendSelection)
        optionMenu.aboutToShow.connect(self.__updateOptionMenu)

        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 .About import About
        About.about(self, "Silx viewer")

    def __forcePlotImageDownward(self):
        silx.config.DEFAULT_PLOT_IMAGE_Y_AXIS_ORIENTATION = "downward"

    def __forcePlotImageUpward(self):
        silx.config.DEFAULT_PLOT_IMAGE_Y_AXIS_ORIENTATION = "upward"

    def __forceMatplotlibBackend(self):
        silx.config.DEFAULT_PLOT_BACKEND = "matplotlib"

    def __forceOpenglBackend(self):
        silx.config.DEFAULT_PLOT_BACKEND = "opengl"

    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)
Beispiel #24
0
class DataPanel(qt.QWidget):

    def __init__(self, parent=None, context=None):
        qt.QWidget.__init__(self, parent=parent)

        self.__customNxdataItem = None

        self.__dataTitle = _HeaderLabel(self)
        self.__dataTitle.setVisible(False)

        self.__dataViewer = DataViewerFrame(self)
        self.__dataViewer.setGlobalHooks(context)

        layout = qt.QVBoxLayout(self)
        layout.setSpacing(0)
        layout.setContentsMargins(0, 0, 0, 0)
        layout.addWidget(self.__dataTitle)
        layout.addWidget(self.__dataViewer)

    def getData(self):
        return self.__dataViewer.data()

    def getCustomNxdataItem(self):
        return self.__customNxdataItem

    def setData(self, data):
        self.__customNxdataItem = None
        self.__dataViewer.setData(data)
        self.__dataTitle.setVisible(data is not None)
        if data is not None:
            self.__dataTitle.setVisible(True)
            if hasattr(data, "name"):
                if hasattr(data, "file"):
                    filename = str(data.file.filename)
                else:
                    filename = ""
                path = data.name
            else:
                filename = ""
                path = ""
            self.__dataTitle.setData(filename, path)

    def setCustomDataItem(self, item):
        self.__customNxdataItem = item
        if item is not None:
            data = item.getVirtualGroup()
        else:
            data = None
        self.__dataViewer.setData(data)
        self.__dataTitle.setVisible(item is not None)
        if item is not None:
            text = item.text()
            self.__dataTitle.setText(text)

    def removeDatasetsFrom(self, root):
        """
        Remove all datasets provided by this root

        .. note:: This function do not update data stored inside
            customNxdataItem cause in the silx-view context this item is
            already updated on his own.

        :param root: The root file of datasets to remove
        """
        data = self.__dataViewer.data()
        if data is not None:
            if data.file is not None:
                # That's an approximation, IS can't be used as h5py generates
                # To objects for each requests to a node
                if data.file.filename == root.file.filename:
                    self.__dataViewer.setData(None)

    def replaceDatasetsFrom(self, removedH5, loadedH5):
        """
        Replace any dataset from any NXdata items using the same dataset name
        from another root.

        Usually used when a file was synchronized.

        .. note:: This function do not update data stored inside
            customNxdataItem cause in the silx-view context this item is
            already updated on his own.

        :param removedRoot: The h5py root file which is replaced
            (which have to be removed)
        :param loadedRoot: The new h5py root file which have to be used
            instread.
        """

        data = self.__dataViewer.data()
        if data is not None:
            if data.file is not None:
                if data.file.filename == removedH5.file.filename:
                    # Try to synchonize the viewed data
                    try:
                        # TODO: It have to update the data without changing the
                        # view which is not so easy
                        newData = loadedH5[data.name]
                        self.__dataViewer.setData(newData)
                    except Exception:
                        _logger.debug("Backtrace", exc_info=True)
Beispiel #25
0
    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.__context = ApplicationContext(self)
        self.__context.restoreLibrarySettings()

        self.__asyncload = False
        self.__dialogState = None
        self.__treeview = silx.gui.hdf5.Hdf5TreeView(self)
        """Silx HDF5 TreeView"""

        # Custom the model to be able to manage the life cycle of the files
        treeModel = silx.gui.hdf5.Hdf5TreeModel(self.__treeview,
                                                ownFiles=False)
        treeModel.sigH5pyObjectLoaded.connect(self.__h5FileLoaded)
        treeModel.sigH5pyObjectRemoved.connect(self.__h5FileRemoved)
        treeModel.sigH5pyObjectSynchronized.connect(self.__h5FileSynchonized)
        treeModel2 = silx.gui.hdf5.NexusSortFilterProxyModel(self.__treeview)
        treeModel2.setSourceModel(treeModel)
        self.__treeview.setModel(treeModel2)

        self.__dataViewer = DataViewerFrame(self)
        self.__dataViewer.setGlobalHooks(self.__context)
        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)
        self.__spliter = spliter

        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._iconUpward = icons.getQIcon('plot-yup')
        self._iconDownward = icons.getQIcon('plot-ydown')

        self.createActions()
        self.createMenus()
        self.__context.restoreSettings()
Beispiel #26
0
 def createDefaultViews(self, parent=None):
     views = list(DataViewerFrame.createDefaultViews(self, parent=parent))
     oldView = [v for v in views if v.modeId() == DataViews.PLOT1D_MODE][0]
     newView = Plot1DViewWithPlugins(parent=parent)
     views[views.index(oldView)] = newView
     return views
Beispiel #27
0
class Hdf5TreeViewExample(qt.QMainWindow):
    """
    This window show an example of use of a Hdf5TreeView.

    The tree is initialized with a list of filenames. A panel allow to play
    with internal property configuration of the widget, and a text screen
    allow to display events.
    """

    def __init__(self, filenames=None):
        """
        :param files_: List of HDF5 or Spec files (pathes or
            :class:`silx.io.spech5.SpecH5` or :class:`h5py.File`
            instances)
        """
        qt.QMainWindow.__init__(self)
        self.setWindowTitle("Silx HDF5 widget example")

        self.__asyncload = False
        self.__treeview = silx.gui.hdf5.Hdf5TreeView(self)
        """Silx HDF5 TreeView"""
        self.__text = qt.QTextEdit(self)
        """Widget displaying information"""

        self.__dataViewer = DataViewerFrame(self)
        vSpliter = qt.QSplitter(qt.Qt.Vertical)
        vSpliter.addWidget(self.__dataViewer)
        vSpliter.addWidget(self.__text)
        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.addWidget(self.createTreeViewConfigurationPanel(self, self.__treeview))
        layout.setStretchFactor(spliter, 1)
        main_panel.setLayout(layout)

        self.setCentralWidget(main_panel)

        # append all files to the tree
        for file_name in filenames:
            self.__treeview.findHdf5TreeModel().appendFile(file_name)

        self.__treeview.activated.connect(self.displayData)
        self.__treeview.activated.connect(lambda index: self.displayEvent("activated", index))
        self.__treeview.clicked.connect(lambda index: self.displayEvent("clicked", index))
        self.__treeview.doubleClicked.connect(lambda index: self.displayEvent("doubleClicked", index))
        self.__treeview.entered.connect(lambda index: self.displayEvent("entered", index))
        self.__treeview.pressed.connect(lambda index: self.displayEvent("pressed", index))

        self.__treeview.addContextMenuCallback(self.customContextMenu)
        # lambda function will never be called cause we store it as weakref
        self.__treeview.addContextMenuCallback(lambda event: None)
        # you have to store it first
        self.__store_lambda = lambda event: self.closeAndSyncCustomContextMenu(event)
        self.__treeview.addContextMenuCallback(self.__store_lambda)

    def displayData(self):
        """Called to update the dataviewer with the selected data.
        """
        selected = list(self.__treeview.selectedH5Nodes())
        if len(selected) == 1:
            # Update the viewer for a single selection
            data = selected[0]
            # data is a hdf5.H5Node object
            # data.h5py_object is a Group/Dataset object (from h5py, spech5, fabioh5)
            # The dataviewer can display both
            self.__dataViewer.setData(data)

    def displayEvent(self, eventName, index):
        """Called to log event in widget
        """
        def formatKey(name, value):
            name, value = silx.utils.html.escape(str(name)), silx.utils.html.escape(str(value))
            return "<li><b>%s</b>: %s</li>" % (name, value)

        text = "<html>"
        text += "<h1>Event</h1>"
        text += "<ul>"
        text += formatKey("name", eventName)
        text += formatKey("index", type(index))
        text += "</ul>"

        text += "<h1>Selected HDF5 objects</h1>"

        for h5_obj in self.__treeview.selectedH5Nodes():
            text += "<h2>HDF5 object</h2>"
            text += "<ul>"
            text += formatKey("local_filename", h5_obj.local_file.filename)
            text += formatKey("local_basename", h5_obj.local_basename)
            text += formatKey("local_name", h5_obj.local_name)
            text += formatKey("real_filename", h5_obj.file.filename)
            text += formatKey("real_basename", h5_obj.basename)
            text += formatKey("real_name", h5_obj.name)

            text += formatKey("obj", h5_obj.ntype)
            text += formatKey("dtype", getattr(h5_obj, "dtype", None))
            text += formatKey("shape", getattr(h5_obj, "shape", None))
            text += formatKey("attrs", getattr(h5_obj, "attrs", None))
            if hasattr(h5_obj, "attrs"):
                text += "<ul>"
                if len(h5_obj.attrs) == 0:
                    text += "<li>empty</li>"
                for key, value in h5_obj.attrs.items():
                    text += formatKey(key, value)
                text += "</ul>"
            text += "</ul>"

        text += "</html>"
        self.__text.setHtml(text)

    def useAsyncLoad(self, useAsync):
        self.__asyncload = useAsync

    def __fileCreated(self, filename):
        if self.__asyncload:
            self.__treeview.findHdf5TreeModel().insertFileAsync(filename)
        else:
            self.__treeview.findHdf5TreeModel().insertFile(filename)

    def customContextMenu(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()
        menu = event.menu()

        hasDataset = False
        for obj in selectedObjects:
            if obj.ntype is h5py.Dataset:
                hasDataset = True
                break

        if not menu.isEmpty():
            menu.addSeparator()

        if hasDataset:
            action = qt.QAction("Do something on the datasets", event.source())
            menu.addAction(action)

    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()
        menu = event.menu()

        if not menu.isEmpty():
            menu.addSeparator()

        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 __hdf5ComboChanged(self, index):
        function = self.__hdf5Combo.itemData(index)
        self.__createHdf5Button.setCallable(function)

    def __edfComboChanged(self, index):
        function = self.__edfCombo.itemData(index)
        self.__createEdfButton.setCallable(function)

    def createTreeViewConfigurationPanel(self, parent, treeview):
        """Create a configuration panel to allow to play with widget states"""
        panel = qt.QWidget(parent)
        panel.setLayout(qt.QHBoxLayout())

        content = qt.QGroupBox("Create HDF5", panel)
        content.setLayout(qt.QVBoxLayout())
        panel.layout().addWidget(content)

        combo = qt.QComboBox()
        combo.addItem("Containing all types", get_hdf5_with_all_types)
        combo.addItem("Containing all links", get_hdf5_with_all_links)
        combo.addItem("Containing 1000 datasets", get_hdf5_with_1000_datasets)
        combo.addItem("Containing 10000 datasets", get_hdf5_with_10000_datasets)
        combo.addItem("Containing 100000 datasets", get_hdf5_with_100000_datasets)
        combo.addItem("Containing recursive links", get_hdf5_with_recursive_links)
        combo.addItem("Containing external recursive links", get_hdf5_with_external_recursive_links)
        combo.addItem("Containing NXdata groups", get_hdf5_with_nxdata)
        combo.activated.connect(self.__hdf5ComboChanged)
        content.layout().addWidget(combo)

        button = ThreadPoolPushButton(content, text="Create")
        button.setCallable(combo.itemData(combo.currentIndex()))
        button.succeeded.connect(self.__fileCreated)
        content.layout().addWidget(button)

        self.__hdf5Combo = combo
        self.__createHdf5Button = button

        asyncload = qt.QCheckBox("Async load", content)
        asyncload.setChecked(self.__asyncload)
        asyncload.toggled.connect(lambda: self.useAsyncLoad(asyncload.isChecked()))
        content.layout().addWidget(asyncload)

        content.layout().addStretch(1)

        content = qt.QGroupBox("Create EDF", panel)
        content.setLayout(qt.QVBoxLayout())
        panel.layout().addWidget(content)

        combo = qt.QComboBox()
        combo.addItem("Containing all types", get_edf_with_all_types)
        combo.addItem("Containing 100000 datasets", get_edf_with_100000_frames)
        combo.activated.connect(self.__edfComboChanged)
        content.layout().addWidget(combo)

        button = ThreadPoolPushButton(content, text="Create")
        button.setCallable(combo.itemData(combo.currentIndex()))
        button.succeeded.connect(self.__fileCreated)
        content.layout().addWidget(button)

        self.__edfCombo = combo
        self.__createEdfButton = button

        content.layout().addStretch(1)

        option = qt.QGroupBox("Tree options", panel)
        option.setLayout(qt.QVBoxLayout())
        panel.layout().addWidget(option)

        sorting = qt.QCheckBox("Enable sorting", option)
        sorting.setChecked(treeview.selectionMode() == qt.QAbstractItemView.MultiSelection)
        sorting.toggled.connect(lambda: treeview.setSortingEnabled(sorting.isChecked()))
        option.layout().addWidget(sorting)

        multiselection = qt.QCheckBox("Multi-selection", option)
        multiselection.setChecked(treeview.selectionMode() == qt.QAbstractItemView.MultiSelection)
        switch_selection = lambda: treeview.setSelectionMode(
            qt.QAbstractItemView.MultiSelection if multiselection.isChecked()
            else qt.QAbstractItemView.SingleSelection)
        multiselection.toggled.connect(switch_selection)
        option.layout().addWidget(multiselection)

        filedrop = qt.QCheckBox("Drop external file", option)
        filedrop.setChecked(treeview.findHdf5TreeModel().isFileDropEnabled())
        filedrop.toggled.connect(lambda: treeview.findHdf5TreeModel().setFileDropEnabled(filedrop.isChecked()))
        option.layout().addWidget(filedrop)

        filemove = qt.QCheckBox("Reorder files", option)
        filemove.setChecked(treeview.findHdf5TreeModel().isFileMoveEnabled())
        filemove.toggled.connect(lambda: treeview.findHdf5TreeModel().setFileMoveEnabled(filedrop.isChecked()))
        option.layout().addWidget(filemove)

        option.layout().addStretch(1)

        option = qt.QGroupBox("Header options", panel)
        option.setLayout(qt.QVBoxLayout())
        panel.layout().addWidget(option)

        autosize = qt.QCheckBox("Auto-size headers", option)
        autosize.setChecked(treeview.header().hasAutoResizeColumns())
        autosize.toggled.connect(lambda: treeview.header().setAutoResizeColumns(autosize.isChecked()))
        option.layout().addWidget(autosize)

        columnpopup = qt.QCheckBox("Popup to hide/show columns", option)
        columnpopup.setChecked(treeview.header().hasHideColumnsPopup())
        columnpopup.toggled.connect(lambda: treeview.header().setEnableHideColumnsPopup(columnpopup.isChecked()))
        option.layout().addWidget(columnpopup)

        define_columns = qt.QComboBox()
        define_columns.addItem("Default columns", treeview.findHdf5TreeModel().COLUMN_IDS)
        define_columns.addItem("Only name and Value", [treeview.findHdf5TreeModel().NAME_COLUMN, treeview.findHdf5TreeModel().VALUE_COLUMN])
        define_columns.activated.connect(lambda index: treeview.header().setSections(define_columns.itemData(index)))
        option.layout().addWidget(define_columns)

        option.layout().addStretch(1)

        panel.layout().addStretch(1)

        return panel
Beispiel #28
0
class DataPanel(qt.QWidget):
    def __init__(self, parent=None, context=None):
        qt.QWidget.__init__(self, parent=parent)

        self.__customNxdataItem = None

        self.__dataTitle = _HeaderLabel(self)
        self.__dataTitle.setVisible(False)

        self.__dataViewer = DataViewerFrame(self)
        self.__dataViewer.setGlobalHooks(context)

        layout = qt.QVBoxLayout(self)
        layout.setSpacing(0)
        layout.setContentsMargins(0, 0, 0, 0)
        layout.addWidget(self.__dataTitle)
        layout.addWidget(self.__dataViewer)

    def getData(self):
        return self.__dataViewer.data()

    def getCustomNxdataItem(self):
        return self.__customNxdataItem

    def setData(self, data):
        self.__customNxdataItem = None
        self.__dataViewer.setData(data)
        self.__dataTitle.setVisible(data is not None)
        if data is not None:
            self.__dataTitle.setVisible(True)
            if hasattr(data, "name"):
                if hasattr(data, "file"):
                    filename = str(data.file.filename)
                else:
                    filename = ""
                path = data.name
            else:
                filename = ""
                path = ""
            self.__dataTitle.setData(filename, path)

    def setCustomDataItem(self, item):
        self.__customNxdataItem = item
        if item is not None:
            data = item.getVirtualGroup()
        else:
            data = None
        self.__dataViewer.setData(data)
        self.__dataTitle.setVisible(item is not None)
        if item is not None:
            text = item.text()
            self.__dataTitle.setText(text)

    def removeDatasetsFrom(self, root):
        """
        Remove all datasets provided by this root

        .. note:: This function do not update data stored inside
            customNxdataItem cause in the silx-view context this item is
            already updated on his own.

        :param root: The root file of datasets to remove
        """
        data = self.__dataViewer.data()
        if data is not None:
            if data.file is not None:
                # That's an approximation, IS can't be used as h5py generates
                # To objects for each requests to a node
                if data.file.filename == root.file.filename:
                    self.__dataViewer.setData(None)

    def replaceDatasetsFrom(self, removedH5, loadedH5):
        """
        Replace any dataset from any NXdata items using the same dataset name
        from another root.

        Usually used when a file was synchronized.

        .. note:: This function do not update data stored inside
            customNxdataItem cause in the silx-view context this item is
            already updated on his own.

        :param removedRoot: The h5py root file which is replaced
            (which have to be removed)
        :param loadedRoot: The new h5py root file which have to be used
            instread.
        """

        data = self.__dataViewer.data()
        if data is not None:
            if data.file is not None:
                if data.file.filename == removedH5.file.filename:
                    # Try to synchonize the viewed data
                    try:
                        # TODO: It have to update the data without changing the
                        # view which is not so easy
                        newData = loadedH5[data.name]
                        self.__dataViewer.setData(newData)
                    except Exception:
                        _logger.debug("Backtrace", exc_info=True)