Commit dce30a04 authored by Damien Naudet's avatar Damien Naudet

Refactored the views.

Simplified their creation.
Views creation are now handled by the nodes.
parent deffcbe6
...@@ -38,14 +38,11 @@ from .widgets.Wizard import XsocsWizard ...@@ -38,14 +38,11 @@ from .widgets.Wizard import XsocsWizard
from .widgets.ProjectChooser import ProjectChooserDialog from .widgets.ProjectChooser import ProjectChooserDialog
from .view.FitView import FitView from .view.FitView import FitView
from .view.QspaceView import QSpaceView
from .view.IntensityView import IntensityView
from .model.TreeView import TreeView from .model.TreeView import TreeView
from .model.ModelDef import ModelRoles from .model.ModelDef import ModelRoles
from .model.Model import Model, RootNode from .model.Model import Model, RootNode
from .process.FitWidget import FitWidget
from .process.RecipSpaceWidget import RecipSpaceWidget from .process.RecipSpaceWidget import RecipSpaceWidget
from .project.FitGroup import FitItem from .project.FitGroup import FitItem
...@@ -53,6 +50,9 @@ from .project.QSpaceGroup import QSpaceItem ...@@ -53,6 +50,9 @@ from .project.QSpaceGroup import QSpaceItem
from .project.XsocsProject import XsocsProject from .project.XsocsProject import XsocsProject
from .project.IntensityGroup import IntensityGroup from .project.IntensityGroup import IntensityGroup
from .project.Hdf5Nodes import setH5NodeFactory, H5File from .project.Hdf5Nodes import setH5NodeFactory, H5File
from .project.ProjectNodes import (IntensityGroupNode,
QSpaceItemNode,
FitItemNode)
from .project.XsocsH5Factory import XsocsH5Factory, h5NodeToProjectItem from .project.XsocsH5Factory import XsocsH5Factory, h5NodeToProjectItem
...@@ -141,13 +141,13 @@ class XsocsGui(Qt.QMainWindow): ...@@ -141,13 +141,13 @@ class XsocsGui(Qt.QMainWindow):
""" """
tree = ProjectTree() tree = ProjectTree()
tree.setShowUniqueGroup(False) tree.setShowUniqueGroup(False)
tree.sigDelegateEvent.connect(self.__viewEvent) tree.sigDelegateEvent.connect(self.__slotViewEvent)
model = ProjectModel(parent=tree) model = ProjectModel(parent=tree)
model.startModel() model.startModel()
tree.setModel(model) tree.setModel(model)
self.setCentralWidget(tree) self.setCentralWidget(tree)
def __viewEvent(self, node, event): def __slotViewEvent(self, node, event):
projectItem = h5NodeToProjectItem(node) projectItem = h5NodeToProjectItem(node)
if projectItem is None: if projectItem is None:
raise ValueError('Unknwown event for node {0} : {1}.' raise ValueError('Unknwown event for node {0} : {1}.'
...@@ -167,28 +167,23 @@ class XsocsGui(Qt.QMainWindow): ...@@ -167,28 +167,23 @@ class XsocsGui(Qt.QMainWindow):
''.format(projectItem, event)) ''.format(projectItem, event))
def __showIntensity(self, node=None): def __showIntensity(self, node=None):
if self.__project is None: if node is None:
intensityGroup = self.__project.intensityGroup()
index = self.tree.pathToIndex(intensityGroup.path)
node = index.data(ModelRoles.InternalDataRole)
elif not isinstance(node, IntensityGroupNode):
return return
view = self.__intensityView
if not view: view = node.getView(self)
if node is None:
intensityGroup = self.__project.intensityGroup()
index = self.tree.pathToIndex(intensityGroup.path)
node = index.data(ModelRoles.InternalDataRole)
# TODO : log if node is None
self.__intensityView = view = IntensityView(self,
model=node.model,
node=node)
screen = Qt.QApplication.desktop()
size = screen.availableGeometry(view).size()
size.scale(size.width() * 0.6,
size.height() * 0.6,
Qt.Qt.IgnoreAspectRatio)
view.resize(size)
view.sigProcessApplied.connect(self.__intensityRoiApplied)
view.show() view.show()
view.setAttribute(Qt.Qt.WA_DeleteOnClose, True)
view.raise_() view.raise_()
# screen = Qt.QApplication.desktop()
# size = screen.availableGeometry(view).size()
# size.scale(size.width() * 0.6,
# size.height() * 0.6,
# Qt.Qt.IgnoreAspectRatio)
# view.resize(size)
def __intensityRoiApplied(self, event): def __intensityRoiApplied(self, event):
xsocsFile = os.path.basename(self.__project.xsocsFile) xsocsFile = os.path.basename(self.__project.xsocsFile)
...@@ -216,18 +211,11 @@ class XsocsGui(Qt.QMainWindow): ...@@ -216,18 +211,11 @@ class XsocsGui(Qt.QMainWindow):
tree = property(lambda self: self.centralWidget()) tree = property(lambda self: self.centralWidget())
def __showQSpace(self, node, bringToFront=True): def __showQSpace(self, node, bringToFront=True):
view = self.__qspaceViews.get(node) if not isinstance(node, QSpaceItemNode):
if not view: return
view = QSpaceView(self, model=node.model, node=node) view = node.getView(self)
self.__qspaceViews[node] = view
screen = Qt.QApplication.desktop()
size = screen.availableGeometry(view).size()
size.scale(size.width() * 0.6,
size.height() * 0.6,
Qt.Qt.IgnoreAspectRatio)
view.resize(size)
view.sigFitDone.connect(self.__slotFitDone)
view.show() view.show()
view.setAttribute(Qt.Qt.WA_DeleteOnClose, True)
if bringToFront: if bringToFront:
view.raise_() view.raise_()
return view return view
...@@ -243,28 +231,19 @@ class XsocsGui(Qt.QMainWindow): ...@@ -243,28 +231,19 @@ class XsocsGui(Qt.QMainWindow):
self.__showFit(index.data(ModelRoles.InternalDataRole)) self.__showFit(index.data(ModelRoles.InternalDataRole))
def __showFit(self, node): def __showFit(self, node):
view = self.__fitViews.get(node) if not isinstance(node, FitItemNode):
if not view: return
# TODO : unmaintainable and FUGLY!!!!! node.parent().parent() view = node.getView(self)
view = FitView(self, node.model, node, node.parent().parent()) view.setAttribute(Qt.Qt.WA_DeleteOnClose, True)
self.__fitViews[node] = view view.sigPointSelected.connect(self.__fitViewPointSelected)
view.sigPointSelected.connect(self.__fitViewPointSelected)
view.show() view.show()
return view
def __fitViewPointSelected(self, point): def __fitViewPointSelected(self, point):
sender = self.sender() sender = self.sender()
if not isinstance(sender, FitView): if not isinstance(sender, FitView):
return return
views = list(self.__fitViews.values())
try:
viewIdx = views.index(sender)
except ValueError:
# TODO
return
fitNode = list(self.__fitViews.keys())[viewIdx]
qspaceNode = fitNode.parent().parent() qspaceNode = sender.getFitNode().parent().parent()
qspaceView = self.__showQSpace(qspaceNode, bringToFront=False) qspaceView = self.__showQSpace(qspaceNode, bringToFront=False)
qspaceView.selectPoint(point.x, point.y) qspaceView.selectPoint(point.x, point.y)
......
...@@ -355,6 +355,11 @@ class Node(object): ...@@ -355,6 +355,11 @@ class Node(object):
self._connect() self._connect()
def _setupNode(self): def _setupNode(self):
"""
Called each time the subject or the branchName change, or the node
is started, only if the subject is set and the node is started.
:return:
"""
pass pass
def _getDepth(self): def _getDepth(self):
......
...@@ -30,6 +30,7 @@ __license__ = "MIT" ...@@ -30,6 +30,7 @@ __license__ = "MIT"
__date__ = "01/11/2016" __date__ = "01/11/2016"
import os import os
import weakref
from silx.gui import qt as Qt, icons from silx.gui import qt as Qt, icons
...@@ -40,6 +41,10 @@ from .IntensityGroup import IntensityItem ...@@ -40,6 +41,10 @@ from .IntensityGroup import IntensityItem
from .XsocsH5Factory import h5NodeToProjectItem from .XsocsH5Factory import h5NodeToProjectItem
from .Hdf5Nodes import H5GroupNode, H5NodeClassDef, H5DatasetNode from .Hdf5Nodes import H5GroupNode, H5NodeClassDef, H5DatasetNode
from ..view.FitView import FitView
from ..view.QspaceView import QSpaceView
from ..view.IntensityView import IntensityView
class ScatterPlotButton(EditorMixin, Qt.QWidget): class ScatterPlotButton(EditorMixin, Qt.QWidget):
persistent = True persistent = True
...@@ -93,6 +98,26 @@ class QSpaceButton(EditorMixin, Qt.QWidget): ...@@ -93,6 +98,26 @@ class QSpaceButton(EditorMixin, Qt.QWidget):
class IntensityGroupNode(H5GroupNode): class IntensityGroupNode(H5GroupNode):
editors = ScatterPlotButton editors = ScatterPlotButton
def __init__(self, *args, **kwargs):
super(IntensityGroupNode, self).__init__(*args, **kwargs)
self.__viewWidget = None
def getView(self, parent=None):
"""
Returns a IntensityView for this item's data.
:param parent:
:return:
"""
view = self.__viewWidget
if view is None or view() is None:
view = weakref.ref(IntensityView(parent,
self.model,
self))
self.__viewWidget = view
return view()
# def _loadChildren(self): # def _loadChildren(self):
# return [] # return []
...@@ -114,6 +139,24 @@ class IntensityNode(H5DatasetNode): ...@@ -114,6 +139,24 @@ class IntensityNode(H5DatasetNode):
class QSpaceItemNode(H5GroupNode): class QSpaceItemNode(H5GroupNode):
editors = QSpaceButton editors = QSpaceButton
def __init__(self, *args, **kwargs):
super(QSpaceItemNode, self).__init__(*args, **kwargs)
self.__viewWidget = None
def getView(self, parent=None):
"""
Returns a QSpaceView for this item's data.
:param parent:
:return:
"""
view = self.__viewWidget
if view is None or view() is None:
view = weakref.ref(QSpaceView(parent,
self.model,
self))
self.__viewWidget = view
return view()
class FitButton(EditorMixin, Qt.QWidget): class FitButton(EditorMixin, Qt.QWidget):
persistent = True persistent = True
...@@ -139,7 +182,6 @@ class FitButton(EditorMixin, Qt.QWidget): ...@@ -139,7 +182,6 @@ class FitButton(EditorMixin, Qt.QWidget):
layout.addStretch(1) layout.addStretch(1)
def __clicked(self): def __clicked(self):
# node = self.node
event = {'event': 'fit'} event = {'event': 'fit'}
self.notifyView(event) self.notifyView(event)
...@@ -171,3 +213,25 @@ class FitItemNode(H5GroupNode): ...@@ -171,3 +213,25 @@ class FitItemNode(H5GroupNode):
def _loadChildren(self): def _loadChildren(self):
return [] return []
def __init__(self, *args, **kwargs):
super(FitItemNode, self).__init__(*args, **kwargs)
self.__viewWidget = None
def getView(self, parent=None):
"""
Returns a FitView for this item's data.
:param parent:
:return:
"""
view = self.__viewWidget
if view is None or view() is None:
view = weakref.ref(FitView(parent,
self.model,
self))
self.__viewWidget = view
return view()
if __name__ == '__main__':
pass
...@@ -53,7 +53,6 @@ class FitView(Qt.QMainWindow): ...@@ -53,7 +53,6 @@ class FitView(Qt.QMainWindow):
parent, parent,
model, model,
node, node,
qspaceNode,
**kwargs): **kwargs):
super(FitView, self).__init__(parent) super(FitView, self).__init__(parent)
...@@ -63,7 +62,9 @@ class FitView(Qt.QMainWindow): ...@@ -63,7 +62,9 @@ class FitView(Qt.QMainWindow):
item = h5NodeToProjectItem(node) item = h5NodeToProjectItem(node)
fitH5 = self.__fitH5 = item.fitH5 fitH5 = self.__fitH5 = item.fitH5
qspaceItem = h5NodeToProjectItem(qspaceNode)
# TODO : this parent().parent() thing is ugly...
qspaceItem = h5NodeToProjectItem(node.parent().parent())
self.__qspaceH5 = qspaceItem.qspaceH5 self.__qspaceH5 = qspaceItem.qspaceH5
self.__node = node self.__node = node
...@@ -165,8 +166,6 @@ class FitView(Qt.QMainWindow): ...@@ -165,8 +166,6 @@ class FitView(Qt.QMainWindow):
self.setCentralWidget(centralWid) self.setCentralWidget(centralWid)
self.__sigInitPlots.connect(self.__firstInit, Qt.Qt.QueuedConnection)
def getFitNode(self): def getFitNode(self):
return self.__node return self.__node
...@@ -186,22 +185,33 @@ class FitView(Qt.QMainWindow): ...@@ -186,22 +185,33 @@ class FitView(Qt.QMainWindow):
super(FitView, self).showEvent(event) super(FitView, self).showEvent(event)
if self.__firstShow: if self.__firstShow:
self.__firstShow = False self.__firstShow = False
self.__sigInitPlots.emit() self.__firstInit()
# self.__sigInitPlots.emit()
def __firstInit(self): def __firstInit(self):
""" """
Called asynchronously the first time the window is shown. Called the first time the window is shown.
This allows us to show the window even though it is not completely
ready yet (so that the user doesn't have to wait for too long
before seeing some results).
:return: :return:
""" """
initDiag = Qt.QProgressDialog('Setting up fit view.', 'cc', 0, 100,
parent=self.parent())
initDiag.setWindowTitle('Please wait...')
initDiag.setCancelButton(None)
initDiag.setAttribute(Qt.Qt.WA_DeleteOnClose)
initDiag.show()
initDiag.setValue(10)
self.__initPlots() self.__initPlots()
initDiag.setValue(40)
self.__startModel() self.__startModel()
initDiag.setValue(70)
tree = self.__tree tree = self.__tree
root = self.__model.index(0, 0, tree.rootIndex()) root = self.__model.index(0, 0, tree.rootIndex())
tree.setRootIndex(self.__model.index(0, 0, root)) tree.setRootIndex(self.__model.index(0, 0, root))
initDiag.setValue(90)
tree.expandAll() tree.expandAll()
initDiag.setValue(100)
initDiag.accept()
initDiag.close()
def __startModel(self): def __startModel(self):
""" """
......
...@@ -232,16 +232,10 @@ class IntensityView(Qt.QMainWindow): ...@@ -232,16 +232,10 @@ class IntensityView(Qt.QMainWindow):
self.addDockWidget(Qt.Qt.LeftDockWidgetArea, dock) self.addDockWidget(Qt.Qt.LeftDockWidgetArea, dock)
self.__roiManager = roiManager = ImageRoiManager(plotWindow) self.__roiManager = roiManager = ImageRoiManager(plotWindow)
# roiToolBar = roiManager.toolBar(rois=['rectangle'],
# options=['show'])
# roiToolBar.addSeparator()
# plotWindow.addToolBarBreak()
# plotWindow.addToolBar(roiToolBar)
rectRoiWidget = RectRoiWidget(roiManager) rectRoiWidget = RectRoiWidget(roiManager)
rectRoiWidget.sigRoiApplied.connect(self.__roiApplied) rectRoiWidget.sigRoiApplied.connect(self.__roiApplied)
dock = Qt.QDockWidget(self) dock = Qt.QDockWidget(self)
dock.setWidget(rectRoiWidget) dock.setWidget(rectRoiWidget)
features = dock.features() ^ Qt.QDockWidget.DockWidgetClosable features = dock.features() ^ Qt.QDockWidget.DockWidgetClosable
...@@ -257,32 +251,6 @@ class IntensityView(Qt.QMainWindow): ...@@ -257,32 +251,6 @@ class IntensityView(Qt.QMainWindow):
def setPlotData(self, x, y, data): def setPlotData(self, x, y, data):
plot = self.__plotWindow plot = self.__plotWindow
plot.setPlotData(x, y, data) plot.setPlotData(x, y, data)
# if data.ndim == 1:
# # scatter
# min_, max_ = data.min(), data.max()
# colormap = cm.jet
# colors = colormap((data.astype(np.float64) - min_) / (max_ - min_))
# plot.addCurve(x, y,
# color=colors,
# symbol='s',
# linestyle='')
# elif data.ndim == 2:
# # image
# min_, max_ = data.min(), data.max()
# colormap = {'name': 'temperature',
# 'normalization': 'linear',
# 'autoscale': True,
# 'vmin': min_,
# 'vmax': max_}
# origin = x[0], y[0]
# scale = (x[-1] - x[0]) / len(x), (y[-1] - y[0]) / len(y)
# plot.addImage(data,
# origin=origin,
# scale=scale,
# colormap=colormap)
# else:
# raise ValueError('data has {0} dimensions, expected 1 or 2.'
# ''.format(data.ndim))
def __roiApplied(self, roi): def __roiApplied(self, roi):
self.sigProcessApplied.emit(roi) self.sigProcessApplied.emit(roi)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment