Skip to content

Commit

Permalink
Refs #1037: Unit test for mantid plot python proxies
Browse files Browse the repository at this point in the history
Exposed the close() method to python so that the windows close properly from python.
Refs #4282: make sure the FloatingWindow is deleted when closed.
Testing several proxy methods. Russell: Layer.legend() and Layer.grid() do not work for me!
  • Loading branch information
Janik Zikovsky committed Jan 9, 2012
1 parent 6a45d65 commit 2c795e4
Show file tree
Hide file tree
Showing 7 changed files with 196 additions and 17 deletions.
2 changes: 1 addition & 1 deletion Code/Mantid/Framework/MPIAlgorithms/scripts/run.sh
Original file line number Diff line number Diff line change
@@ -1 +1 @@
MANTIDPATH=~/Mantid/Code/mpi-build/bin PYTHONPATH=$MANTIDPATH mpirun -np $2 python $1
MANTIDPATH=~/Code/Mantid/Code/mpi-framework/bin PYTHONPATH=$MANTIDPATH mpirun -np $2 python $1
1 change: 1 addition & 0 deletions Code/Mantid/MantidPlot/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -825,6 +825,7 @@ add_custom_command ( TARGET MantidPlot POST_BUILD
set ( MANTIDPLOT_TEST_PY_FILES
MantidPlotSliceViewerTest.py
MantidPlot1DPlotTest.py
MantidPlotProxiesTest.py
)

if ( 0 )
Expand Down
2 changes: 2 additions & 0 deletions Code/Mantid/MantidPlot/src/ApplicationWindow.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17472,6 +17472,8 @@ void ApplicationWindow::removeFloatingWindow(FloatingWindow* w)
{
closeWindow(w->mdiSubWindow());
}
// Make the FloatingWindow delete itself
w->deleteLater();
}
}

Expand Down
76 changes: 76 additions & 0 deletions Code/Mantid/MantidPlot/src/MdiSubWindow.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -469,6 +469,10 @@ d_app(appWindow)
setFocusPolicy(Qt::StrongFocus);
connect(appWindow,SIGNAL(shutting_down()),this,SLOT(close()));
m_flags = windowFlags();
// Window must NOT get deleted automatically when closed.
// Instead, the ApplicationWindow->removeFloatingWindow() call takes care of
// calling deleteLater().
setAttribute(Qt::WA_DeleteOnClose, false);
}

/**
Expand Down Expand Up @@ -536,3 +540,75 @@ void FloatingWindow::removeStaysOnTopFlag()
}
}

/** Sets the underlying MdiSubWindow */
void FloatingWindow::setMdiSubWindow(MdiSubWindow* sw)
{
setWidget(sw);
}


/** removes the underlying MdiSubWindow */
void FloatingWindow::removeMdiSubWindow()
{
MdiSubWindowParent_t* wrapper = dynamic_cast<MdiSubWindowParent_t*>(centralWidget());
if (wrapper)
{
wrapper->setWidget(NULL);
}
}

/** Sets the widget displayed in the FloatingWindow
*
* @param w :: MdiSubWindow being floated
*/
void FloatingWindow::setWidget(QWidget* w)
{
MdiSubWindowParent_t* wrapper = new MdiSubWindowParent_t(this);
wrapper->setWidget(w);
setCentralWidget(wrapper);
}

//
///**
// * Handle the close event.
// * @param e :: A QCloseEvent event.
// */
//void FloatingWindow::closeEvent( QCloseEvent *e )
//{
// // Default result = do close.
// int result = 0;
//
//// // If you need to confirm the close, ask the user
//// if (d_confirm_close)
//// {
//// result = QMessageBox::information(this, tr("MantidPlot"),
//// tr("Do you want to hide or delete") + "<p><b>'" + objectName() + "'</b> ?",
//// tr("Delete"), tr("Hide"), tr("Cancel"), 0, 2);
//// }
//
// switch(result)
// {
// case 0:
// if (widget()->close())
// {
// e->accept();
// // Continue; the mdi window should close (?)
// }
// else
// {
// QMessageBox::critical(parentWidget(),"MantidPlot - Error", "Window cannot be closed");
// e->ignore();
// }
// break;
//
//// case 1:
//// e->ignore();
//// emit hiddenWindow(this);
//// break;
////
//// case 2:
//// e->ignore();
//// break;
// }
//
//}
23 changes: 7 additions & 16 deletions Code/Mantid/MantidPlot/src/MdiSubWindow.h
Original file line number Diff line number Diff line change
Expand Up @@ -267,6 +267,9 @@ public slots:

typedef QList<MdiSubWindow*> MDIWindowList;


//==============================================================================
//==============================================================================
/**
* Floating wrapper window for a MdiSubWindow.
*/
Expand All @@ -278,25 +281,13 @@ class FloatingWindow: public QMainWindow
void setStaysOnTopFlag();
void removeStaysOnTopFlag();
MdiSubWindow* mdiSubWindow() {return static_cast<MdiSubWindow*>(widget());}
void setMdiSubWindow(MdiSubWindow* sw) {setWidget(sw);}
void removeMdiSubWindow()
{
MdiSubWindowParent_t* wrapper = dynamic_cast<MdiSubWindowParent_t*>(centralWidget());
if (wrapper)
{
wrapper->setWidget(NULL);
}
}
void setMdiSubWindow(MdiSubWindow* sw);
void removeMdiSubWindow();

protected:

void setWidget(QWidget* w)
{
MdiSubWindowParent_t* wrapper = new MdiSubWindowParent_t(this);
wrapper->setWidget(w);
setCentralWidget(wrapper);
}
void setWidget(QWidget* w);
QWidget* widget() {return static_cast<MdiSubWindowParent_t*>(centralWidget())->widget();}

virtual bool event(QEvent * e);
ApplicationWindow* d_app;
Qt::WindowFlags m_flags;
Expand Down
1 change: 1 addition & 0 deletions Code/Mantid/MantidPlot/src/qti.sip
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ public:
Folder* folder();

void askOnCloseEvent(bool)/PyName=confirmClose/;
bool close();

private:
MdiSubWindow(const MdiSubWindow&);
Expand Down
108 changes: 108 additions & 0 deletions Code/Mantid/MantidPlot/test/MantidPlotProxiesTest.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
"""
Test the use of proxy objects in MantidPlot that
prevent crashes when accessing the python object
after deletion of the object
"""
import mantidplottests
from mantidplottests import *
import time
import numpy as np
from PyQt4 import QtGui, QtCore

# =============== Create a fake workspace to plot =======================
X1 = np.linspace(0,10, 100)
Y1 = 1000*(np.sin(X1)**2) + X1*10
X1 = np.append(X1, 10.1)

X2 = np.linspace(2,12, 100)
Y2 = 500*(np.cos(X2/2.)**2) + 20
X2 = np.append(X2, 12.10)

X = np.append(X1, X2)
Y = np.append(Y1, Y2)
E = np.sqrt(Y)

CreateWorkspace(OutputWorkspace="fake", DataX=list(X), DataY=list(Y), DataE=list(E), NSpec=2, UnitX="TOF", YUnitLabel="Counts", WorkspaceTitle="Faked data Workspace")

class MantidPlotProxiesTest(unittest.TestCase):

def setUp(self):
pass

def tearDown(self):
"""Clean up by closing the created window """
pass

def try_closing(self, obj, msg=""):
""" Try closing a graphical object, and
access the variable to see if it has been set to None """
# No closing dialog
obj.confirmClose(False)
# This should close (and hopefully delete) obj
obj.close()
# Make sure the event passes
QtCore.QCoreApplication.processEvents()
QtCore.QCoreApplication.processEvents()
# Check that the object has been None'd
self.assertTrue(obj._getHeldObject() is None, msg + "'s return value gets cleared when closed.")

def test_closing_retrieved_object(self):
"""Create object using newXXX("name"), retrieve it using XXX("name") and then close it """
for cmd in ['table', 'matrix', 'graph', 'note']:
name = "testobject%s" % cmd
# Create a method called newTable, for example
newMethod = "new" + cmd[0].upper() + cmd[1:] + '("%s")' % name
eval(newMethod)
obj = eval(cmd + '("%s")' % name)
self.try_closing(obj, cmd+"()")

def test_closing_newTable(self):
obj = newTable()
self.try_closing(obj, "newTable()")

def test_closing_newMatrix(self):
obj = newMatrix()
self.try_closing(obj, "newMatrix()")

def test_closing_newPlot3D(self):
obj = newPlot3D()
self.try_closing(obj, "newPlot3D()")

def test_closing_newNote(self):
obj = newNote()
self.try_closing(obj, "newNote()")

def test_closing_newGraph(self):
obj = newGraph()
self.try_closing(obj, "newGraph()")

def test_closing_layers(self):
g = newGraph()
l0 = g.layer(0)
l1 = g.addLayer()
l_active = g.activeLayer()
self.try_closing(g, "newGraph()")
self.assertTrue(l0._getHeldObject() is None, "Layer object 0 from deleted graph is None")
self.assertTrue(l1._getHeldObject() is None, "Layer object 1 from deleted graph is None")
self.assertTrue(l_active._getHeldObject() is None, "Active Layer object from deleted graph is None")

def test_closing_Layer_objects(self):
g = plotSpectrum("fake", [0,1])
l = g.activeLayer()

return
# FIXME! The following calls fail:
legend = l.legend()
legend2 = l.newLegend()
grid = l.grid()
self.assertTrue(legend._getHeldObject() is None, "Deleted legend safely")
self.assertTrue(legend2._getHeldObject() is None, "Deleted new legend safely")
self.assertTrue(grid._getHeldObject() is None, "Deleted grid safely")

#spectrogram = l.spectrogram()
#self.assertTrue(spectrogram._getHeldObject() is None, "Deleted spectrogram safely")


# Run the unit tests
mantidplottests.runTests(MantidPlotProxiesTest)

0 comments on commit 2c795e4

Please sign in to comment.