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
from .widgets.ProjectChooser import ProjectChooserDialog
from .view.FitView import FitView
from .view.QspaceView import QSpaceView
from .view.IntensityView import IntensityView
from .model.TreeView import TreeView
from .model.ModelDef import ModelRoles
from .model.Model import Model, RootNode
from .process.FitWidget import FitWidget
from .process.RecipSpaceWidget import RecipSpaceWidget
from .project.FitGroup import FitItem
......@@ -53,6 +50,9 @@ from .project.QSpaceGroup import QSpaceItem
from .project.XsocsProject import XsocsProject
from .project.IntensityGroup import IntensityGroup
from .project.Hdf5Nodes import setH5NodeFactory, H5File
from .project.ProjectNodes import (IntensityGroupNode,
QSpaceItemNode,
FitItemNode)
from .project.XsocsH5Factory import XsocsH5Factory, h5NodeToProjectItem
......@@ -141,13 +141,13 @@ class XsocsGui(Qt.QMainWindow):
"""
tree = ProjectTree()
tree.setShowUniqueGroup(False)
tree.sigDelegateEvent.connect(self.__viewEvent)
tree.sigDelegateEvent.connect(self.__slotViewEvent)
model = ProjectModel(parent=tree)
model.startModel()
tree.setModel(model)
self.setCentralWidget(tree)
def __viewEvent(self, node, event):
def __slotViewEvent(self, node, event):
projectItem = h5NodeToProjectItem(node)
if projectItem is None:
raise ValueError('Unknwown event for node {0} : {1}.'
......@@ -167,28 +167,23 @@ class XsocsGui(Qt.QMainWindow):
''.format(projectItem, event))
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
view = self.__intensityView
if not view:
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 = node.getView(self)
view.show()
view.setAttribute(Qt.Qt.WA_DeleteOnClose, True)
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):
xsocsFile = os.path.basename(self.__project.xsocsFile)
......@@ -216,18 +211,11 @@ class XsocsGui(Qt.QMainWindow):
tree = property(lambda self: self.centralWidget())
def __showQSpace(self, node, bringToFront=True):
view = self.__qspaceViews.get(node)
if not view:
view = QSpaceView(self, model=node.model, node=node)
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)
if not isinstance(node, QSpaceItemNode):
return
view = node.getView(self)
view.show()
view.setAttribute(Qt.Qt.WA_DeleteOnClose, True)
if bringToFront:
view.raise_()
return view
......@@ -243,28 +231,19 @@ class XsocsGui(Qt.QMainWindow):
self.__showFit(index.data(ModelRoles.InternalDataRole))
def __showFit(self, node):
view = self.__fitViews.get(node)
if not view:
# TODO : unmaintainable and FUGLY!!!!! node.parent().parent()
view = FitView(self, node.model, node, node.parent().parent())
self.__fitViews[node] = view
view.sigPointSelected.connect(self.__fitViewPointSelected)
if not isinstance(node, FitItemNode):
return
view = node.getView(self)
view.setAttribute(Qt.Qt.WA_DeleteOnClose, True)
view.sigPointSelected.connect(self.__fitViewPointSelected)
view.show()
return view
def __fitViewPointSelected(self, point):
sender = self.sender()
if not isinstance(sender, FitView):
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.selectPoint(point.x, point.y)
......
......@@ -355,6 +355,11 @@ class Node(object):
self._connect()
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
def _getDepth(self):
......
......@@ -30,6 +30,7 @@ __license__ = "MIT"
__date__ = "01/11/2016"
import os
import weakref
from silx.gui import qt as Qt, icons
......@@ -40,6 +41,10 @@ from .IntensityGroup import IntensityItem
from .XsocsH5Factory import h5NodeToProjectItem
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):
persistent = True
......@@ -93,6 +98,26 @@ class QSpaceButton(EditorMixin, Qt.QWidget):
class IntensityGroupNode(H5GroupNode):
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):
# return []
......@@ -114,6 +139,24 @@ class IntensityNode(H5DatasetNode):
class QSpaceItemNode(H5GroupNode):
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):
persistent = True
......@@ -139,7 +182,6 @@ class FitButton(EditorMixin, Qt.QWidget):
layout.addStretch(1)
def __clicked(self):
# node = self.node
event = {'event': 'fit'}
self.notifyView(event)
......@@ -171,3 +213,25 @@ class FitItemNode(H5GroupNode):
def _loadChildren(self):
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):
parent,
model,
node,
qspaceNode,
**kwargs):
super(FitView, self).__init__(parent)
......@@ -63,7 +62,9 @@ class FitView(Qt.QMainWindow):
item = h5NodeToProjectItem(node)
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.__node = node
......@@ -165,8 +166,6 @@ class FitView(Qt.QMainWindow):
self.setCentralWidget(centralWid)
self.__sigInitPlots.connect(self.__firstInit, Qt.Qt.QueuedConnection)
def getFitNode(self):
return self.__node
......@@ -186,22 +185,33 @@ class FitView(Qt.QMainWindow):
super(FitView, self).showEvent(event)
if self.__firstShow:
self.__firstShow = False
self.__sigInitPlots.emit()
self.__firstInit()
# self.__sigInitPlots.emit()
def __firstInit(self):
"""
Called asynchronously 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).
Called the first time the window is shown.
: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()
initDiag.setValue(40)
self.__startModel()
initDiag.setValue(70)
tree = self.__tree
root = self.__model.index(0, 0, tree.rootIndex())
tree.setRootIndex(self.__model.index(0, 0, root))
initDiag.setValue(90)
tree.expandAll()
initDiag.setValue(100)
initDiag.accept()
initDiag.close()
def __startModel(self):
"""
......
......@@ -232,16 +232,10 @@ class IntensityView(Qt.QMainWindow):
self.addDockWidget(Qt.Qt.LeftDockWidgetArea, dock)
self.__roiManager = roiManager = ImageRoiManager(plotWindow)
# roiToolBar = roiManager.toolBar(rois=['rectangle'],
# options=['show'])
# roiToolBar.addSeparator()
# plotWindow.addToolBarBreak()
# plotWindow.addToolBar(roiToolBar)
rectRoiWidget = RectRoiWidget(roiManager)
rectRoiWidget.sigRoiApplied.connect(self.__roiApplied)
dock = Qt.QDockWidget(self)
dock.setWidget(rectRoiWidget)
features = dock.features() ^ Qt.QDockWidget.DockWidgetClosable
......@@ -257,32 +251,6 @@ class IntensityView(Qt.QMainWindow):
def setPlotData(self, x, y, data):
plot = self.__plotWindow
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):
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