Skip to content

Commit

Permalink
Split up mantidplot.py and move it into a directory. Re #1037.
Browse files Browse the repository at this point in the history
mantidplot.py is starting to get big, and once all the proxy business
for qti objects is added is will really swell. So the proxy objects
will go in a separate file and everything is in a mantidplot directory
that is imported. It shouldn't matter if an old mantidplot.py is lying
around in the old place - python will prefer to import the directory.
Fingers crossed that I've got the installation settings right.
  • Loading branch information
RussellTaylor committed Dec 30, 2011
1 parent e4910bf commit 4564706
Show file tree
Hide file tree
Showing 4 changed files with 128 additions and 115 deletions.
5 changes: 4 additions & 1 deletion Code/Mantid/MantidPlot/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -791,7 +791,7 @@ endif( WIN32 )
# Now copy the required python files into the build destination
###########################################################################

set ( PYTHON_INSTALL_FILES qtiplotrc.py qtiUtil.py mantidplot.py mantidplotrc.py )
set ( PYTHON_INSTALL_FILES qtiplotrc.py qtiUtil.py mantidplotrc.py )
foreach ( PYFILE ${PYTHON_INSTALL_FILES} )
# Command to copy when MantidPlot rebuilds. Does not work if the .py files ONLY were modified!
add_custom_command ( TARGET MantidPlot POST_BUILD
Expand All @@ -805,6 +805,8 @@ foreach ( PYFILE ${PYTHON_INSTALL_FILES} )
configure_file( ${CMAKE_CURRENT_SOURCE_DIR}/${PYFILE} ${CMAKE_LIBRARY_OUTPUT_DIRECTORY}/${CMAKE_CFG_INTDIR} COPYONLY )
endforeach ( PYFILE ${PYTHON_INSTALL_FILES} )

file ( COPY mantidplot DESTINATION ${CMAKE_LIBRARY_OUTPUT_DIRECTORY}/${CMAKE_CFG_INTDIR} )

###########################################################################
# MantidPlot Python Unit Tests
###########################################################################
Expand Down Expand Up @@ -868,6 +870,7 @@ install ( TARGETS MantidPlot RUNTIME DESTINATION ${BIN_DIR}
BUNDLE DESTINATION .
)
install ( FILES ${PYTHON_INSTALL_FILES} DESTINATION ${BIN_DIR} )
install ( DIRECTORY mantidplot DESTINATION ${BIN_DIR} )

if ( APPLE )
configure_file ( ${CMAKE_CURRENT_SOURCE_DIR}/FixBundle.cmake.in
Expand Down
1 change: 1 addition & 0 deletions Code/Mantid/MantidPlot/mantidplot/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
from mantidplot import *
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@

# Grab a few Mantid things so that we can recognise workspace variables
from MantidFramework import WorkspaceProxy, WorkspaceGroup, MatrixWorkspace, mtd, ProxyObject
import proxies
from PyQt4 import QtCore

#-------------------------- Wrapped MantidPlot functions -----------------
Expand Down Expand Up @@ -142,10 +143,10 @@ def plotSlice(source, label="", xydim=None, slicepoint=None,
xydim=xydim, slicepoint=slicepoint, colormin=colormin,
colormax=colormax, colorscalelog=colorscalelog, limits=limits,
**kwargs)
pxy = SliceViewerWindowProxy(window)
pxy = proxies.SliceViewerWindowProxy(window)
out.append(pxy)

# Returh the widget alone if only 1
# Return the widget alone if only 1
if len(out) == 1:
return out[0]
else:
Expand Down Expand Up @@ -209,118 +210,6 @@ def closeAllSliceViewers():
Layer.Top = qti.GraphOptions.Top


#-----------------------------------------------------------------------------
#--------------------------- Proxy Objects -----------------------------------
#-----------------------------------------------------------------------------



#-----------------------------------------------------------------------------
class QtProxyObject(QtCore.QObject):
"""Generic Proxy object for wrapping Qt C++ Qobjects.
This holds the QObject internally and passes methods to it.
When the underlying object is deleted, the reference is set
to None to avoid segfaults.
"""
def __init__(self, toproxy):
QtCore.QObject.__init__(self)
self.__obj = toproxy
# Connect to track the destroyed
QtCore.QObject.connect( self.__obj, QtCore.SIGNAL("destroyed()"),
self._heldObjectDestroyed)

def _heldObjectDestroyed(self):
"""Slot called when the held object is destroyed.
Sets it to None, preventing segfaults """
self._kill_object()

def __getattr__(self, attr):
"""
Reroute a method call to the the stored object
"""
return getattr(self._getHeldObject(), attr)

def __str__(self):
"""
Return a string representation of the proxied object
"""
return str(self._getHeldObject())

def __repr__(self):
"""
Return a string representation of the proxied object
"""
return `self._getHeldObject()`

def _getHeldObject(self):
"""
Returns a reference to the held object
"""
return self.__obj

def _kill_object(self):
"""
Release the stored instance
"""
self.__obj = None

def _swap(self, obj):
"""
Swap an object so that the proxy now refers to this object
"""
self.__obj = obj



#-----------------------------------------------------------------------------
class SliceViewerWindowProxy(QtProxyObject):
"""Proxy for a C++ SliceViewerWindow object.
It will pass-through method calls that can be applied to the
SliceViewer widget contained within.
"""
def __init__(self, toproxy):
QtProxyObject.__init__(self, toproxy)
# List of methods in slicer to pass-through
self.slicer_methods = ["setWorkspace", "getWorkspaceName", "showControls", "openFromXML", "saveImage", "setXYDim", "setXYDim", "getDimX", "getDimY", "setSlicePoint", "setSlicePoint", "getSlicePoint", "getSlicePoint", "setXYLimits", "getXLimits", "getYLimits", "zoomBy", "setXYCenter", "resetZoom", "loadColorMap", "setColorScale", "setColorScaleMin", "setColorScaleMax", "setColorScaleLog", "getColorScaleMin", "getColorScaleMax", "getColorScaleLog", "setColorScaleAutoFull", "setColorScaleAutoSlice", "setFastRender", "getFastRender"]

def __getattr__(self, attr):
"""
Reroute a method call to the the stored object
"""
if self._getHeldObject() is None:
raise Exception("Error! The SliceViewerWindow has been deleted.")

# Pass-through to the contained SliceViewer widget.
sv = self._getHeldObject().getSlicer()
if attr in self.slicer_methods:
return getattr(sv, attr)
else:
return getattr(self._getHeldObject(), attr)

def __str__(self):
"""
Return a string representation of the proxied object
"""
if self._getHeldObject() is None:
return "None"
else:
return 'SliceViewerWindow(workspace="%s")' % self._getHeldObject().getSlicer().getWorkspaceName()

def __repr__(self):
"""
Return a string representation of the proxied object
"""
return `self._getHeldObject()`

def __dir__(self):
"""
Returns the list of attributes for this object.
Might allow tab-completion to work under ipython
"""
return self.slicer_methods





Expand Down
120 changes: 120 additions & 0 deletions Code/Mantid/MantidPlot/mantidplot/proxies.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
"""
Module containing classes that act as proxies to the various MantidPlot gui objects that are
accessible from python. They listen for the QObject 'destroyed' signal and set the wrapped
reference to None, thus ensuring that further attempts at access do not cause a crash.
"""

from PyQt4 import QtCore

#-----------------------------------------------------------------------------
#--------------------------- Proxy Objects -----------------------------------
#-----------------------------------------------------------------------------



#-----------------------------------------------------------------------------
class QtProxyObject(QtCore.QObject):
"""Generic Proxy object for wrapping Qt C++ Qobjects.
This holds the QObject internally and passes methods to it.
When the underlying object is deleted, the reference is set
to None to avoid segfaults.
"""
def __init__(self, toproxy):
QtCore.QObject.__init__(self)
self.__obj = toproxy
# Connect to track the destroyed
QtCore.QObject.connect( self.__obj, QtCore.SIGNAL("destroyed()"),
self._heldObjectDestroyed)

def _heldObjectDestroyed(self):
"""Slot called when the held object is destroyed.
Sets it to None, preventing segfaults """
self._kill_object()

def __getattr__(self, attr):
"""
Reroute a method call to the the stored object
"""
return getattr(self._getHeldObject(), attr)

def __str__(self):
"""
Return a string representation of the proxied object
"""
return str(self._getHeldObject())

def __repr__(self):
"""
Return a string representation of the proxied object
"""
return `self._getHeldObject()`

def _getHeldObject(self):
"""
Returns a reference to the held object
"""
return self.__obj

def _kill_object(self):
"""
Release the stored instance
"""
self.__obj = None

def _swap(self, obj):
"""
Swap an object so that the proxy now refers to this object
"""
self.__obj = obj



#-----------------------------------------------------------------------------
class SliceViewerWindowProxy(QtProxyObject):
"""Proxy for a C++ SliceViewerWindow object.
It will pass-through method calls that can be applied to the
SliceViewer widget contained within.
"""
def __init__(self, toproxy):
QtProxyObject.__init__(self, toproxy)
# List of methods in slicer to pass-through
self.slicer_methods = ["setWorkspace", "getWorkspaceName", "showControls", "openFromXML", "saveImage", "setXYDim", "setXYDim", "getDimX", "getDimY", "setSlicePoint", "setSlicePoint", "getSlicePoint", "getSlicePoint", "setXYLimits", "getXLimits", "getYLimits", "zoomBy", "setXYCenter", "resetZoom", "loadColorMap", "setColorScale", "setColorScaleMin", "setColorScaleMax", "setColorScaleLog", "getColorScaleMin", "getColorScaleMax", "getColorScaleLog", "setColorScaleAutoFull", "setColorScaleAutoSlice", "setFastRender", "getFastRender"]

def __getattr__(self, attr):
"""
Reroute a method call to the the stored object
"""
if self._getHeldObject() is None:
raise Exception("Error! The SliceViewerWindow has been deleted.")

# Pass-through to the contained SliceViewer widget.
sv = self._getHeldObject().getSlicer()
if attr in self.slicer_methods:
return getattr(sv, attr)
else:
return getattr(self._getHeldObject(), attr)

def __str__(self):
"""
Return a string representation of the proxied object
"""
if self._getHeldObject() is None:
return "None"
else:
return 'SliceViewerWindow(workspace="%s")' % self._getHeldObject().getSlicer().getWorkspaceName()

def __repr__(self):
"""
Return a string representation of the proxied object
"""
return `self._getHeldObject()`

def __dir__(self):
"""
Returns the list of attributes for this object.
Might allow tab-completion to work under ipython
"""
return self.slicer_methods


0 comments on commit 4564706

Please sign in to comment.