]> SALOME platform Git repositories - modules/gui.git/commitdiff
Salome HOME
Issue 0020527: EDF 1132 GUI: SIGSEGV at destruction of a Python module with GUI
authorvsr <vsr@opencascade.com>
Fri, 9 Oct 2009 11:25:18 +0000 (11:25 +0000)
committervsr <vsr@opencascade.com>
Fri, 9 Oct 2009 11:25:18 +0000 (11:25 +0000)
src/CAM/CAM_Application.cxx
src/CAM/CAM_Application.h
src/SALOME_PYQT/SALOME_PYQT_GUI/SALOME_PYQT_Module.cxx
src/SALOME_PYQT/SALOME_PYQT_GUILight/SALOME_PYQT_ModuleLight.cxx
src/SALOME_PYQT/SALOME_PYQT_GUILight/SALOME_PYQT_ModuleLight.h

index 61aa42d960222c9af1b1366763eb3eab9cbbb269..dab5b81430a78c10db3e5722e2ed35046a6e9526 100755 (executable)
@@ -88,8 +88,6 @@ CAM_Application::CAM_Application( const bool autoLoad )
 */
 CAM_Application::~CAM_Application()
 {
-  for ( QList<CAM_Module*>::const_iterator it = myModules.begin(); it != myModules.end(); ++it )
-    delete *it;
 }
 
 /*! 
@@ -437,6 +435,13 @@ void CAM_Application::beforeCloseDoc( SUIT_Study* theDoc )
     (*it)->studyClosed( theDoc );
 }
 
+void CAM_Application::afterCloseDoc()
+{
+  for ( QList<CAM_Module*>::const_iterator it = myModules.begin(); it != myModules.end(); ++it )
+    delete *it;
+  myModules.clear();
+}
+
 /*!
   \brief Set active study.
   \param study study to be made active
index 5ce540555e89d284dc6224aba22761ad166cac3f..e04876078828f40beca4e04cd631d960e0f7a3ea 100755 (executable)
@@ -75,6 +75,7 @@ protected:
 
   virtual void        moduleAdded( CAM_Module* );
   virtual void        beforeCloseDoc( SUIT_Study* );
+  virtual void        afterCloseDoc();
   virtual bool        activateModule( CAM_Module* = 0 );
 
   virtual void        setActiveStudy( SUIT_Study* );
index 80da8eb31a42d682843e1dbcd33d5da37f84aa0c..42e24296b5af8ab2bf05f1724e31939b16d85bee 100644 (file)
@@ -157,8 +157,8 @@ void SALOME_PYQT_Module::getEngineIOR()
   if ( !myInterp || !myModule )
     return;
 
-  if ( PyObject_HasAttrString( myModule , "engineIOR" ) ) {
-    PyObjWrapper res( PyObject_CallMethod( myModule, (char*)"engineIOR", (char*)"" ) );
+  if ( PyObject_HasAttrString( myModule->get() , "engineIOR" ) ) {
+    PyObjWrapper res( PyObject_CallMethod( myModule->get(), (char*)"engineIOR", (char*)"" ) );
     if ( !res ) {
       PyErr_Print();
     }
index 986b9e4e308798787daa0205eb13fe2f431e6fad..735f705f460f09eecb44ad4a5ed25d2777fd512a 100644 (file)
@@ -283,6 +283,10 @@ SALOME_PYQT_ModuleLight::~SALOME_PYQT_ModuleLight()
 {
   if ( myXmlHandler )
     delete myXmlHandler;
+  if ( myInterp ) {
+    PyLockWrapper aLock = myInterp->GetLockWrapper();
+    delete myModule;
+  }
 }
 
 /*!
@@ -862,8 +866,8 @@ void SALOME_PYQT_ModuleLight::init( CAM_Application* app )
   PyLockWrapper aLock = myInterp->GetLockWrapper();
   // ... (the Python module is already imported)
   // ... finally call Python module's initialize() method
-  if ( PyObject_HasAttrString( myModule , "initialize" ) ) {
-    PyObjWrapper res( PyObject_CallMethod( myModule, (char*)"initialize", (char*)"" ) );
+  if ( PyObject_HasAttrString( myModule->get(), "initialize" ) ) {
+    PyObjWrapper res( PyObject_CallMethod( myModule->get(), (char*)"initialize", (char*)"" ) );
     if ( !res ) {
       PyErr_Print();
     }
@@ -876,8 +880,8 @@ void SALOME_PYQT_ModuleLight::init( CAM_Application* app )
   myWindowsMap.insert( LightApp_Application::WT_PyConsole,     Qt::BottomDockWidgetArea );
   myWindowsMap.insert( LightApp_Application::WT_LogWindow,     Qt::BottomDockWidgetArea );
 
-  if ( PyObject_HasAttrString( myModule , "windows" ) ) {
-    PyObjWrapper res1( PyObject_CallMethod( myModule, (char*)"windows", (char*)"" ) );
+  if ( PyObject_HasAttrString( myModule->get() , "windows" ) ) {
+    PyObjWrapper res1( PyObject_CallMethod( myModule->get(), (char*)"windows", (char*)"" ) );
     if ( !res1 ) {
       PyErr_Print();
     }
@@ -903,8 +907,8 @@ void SALOME_PYQT_ModuleLight::init( CAM_Application* app )
 
   // get compatible view windows types from the Python module 
   // by calling views() method
-  if ( PyObject_HasAttrString( myModule , "views" ) ) {
-    PyObjWrapper res2( PyObject_CallMethod( myModule, (char*)"views", (char*)"" ) );
+  if ( PyObject_HasAttrString( myModule->get() , "views" ) ) {
+    PyObjWrapper res2( PyObject_CallMethod( myModule->get(), (char*)"views", (char*)"" ) );
     if ( !res2 ) {
       PyErr_Print();
     }
@@ -962,8 +966,8 @@ void SALOME_PYQT_ModuleLight::activate( SUIT_Study* theStudy )
   PyLockWrapper aLock = myInterp->GetLockWrapper();
 
   // call Python module's activate() method (for the new modules)
-  if ( PyObject_HasAttrString( myModule , "activate" ) ) {
-    PyObject* res1 = PyObject_CallMethod( myModule, (char*)"activate", (char*)"" );
+  if ( PyObject_HasAttrString( myModule->get() , "activate" ) ) {
+    PyObject* res1 = PyObject_CallMethod( myModule->get(), (char*)"activate", (char*)"" );
     if ( !res1 || !PyBool_Check( res1 ) ) {
       PyErr_Print();
       // always true for old modules (no return value)
@@ -1035,8 +1039,8 @@ void SALOME_PYQT_ModuleLight::customize( SUIT_Study* theStudy )
 
   if ( IsCallOldMethods ) {
     // call Python module's setSettings() method (obsolete)
-    if ( PyObject_HasAttrString( myModule , "setSettings" ) ) {
-      PyObjWrapper res( PyObject_CallMethod( myModule, (char*)"setSettings", (char*)"" ) );
+    if ( PyObject_HasAttrString( myModule->get() , "setSettings" ) ) {
+      PyObjWrapper res( PyObject_CallMethod( myModule->get(), (char*)"setSettings", (char*)"" ) );
       if( !res ) {
         PyErr_Print();
       }
@@ -1062,8 +1066,8 @@ void SALOME_PYQT_ModuleLight::deactivate( SUIT_Study* theStudy )
     return;
   }
   // then call Python module's deactivate() method
-  if ( PyObject_HasAttrString( myModule , "deactivate" ) ) {
-    PyObjWrapper res( PyObject_CallMethod( myModule, (char*)"deactivate", (char*)"" ) );
+  if ( PyObject_HasAttrString( myModule->get() , "deactivate" ) ) {
+    PyObjWrapper res( PyObject_CallMethod( myModule->get(), (char*)"deactivate", (char*)"" ) );
     if( !res ) {
       PyErr_Print();
     }
@@ -1116,8 +1120,8 @@ void SALOME_PYQT_ModuleLight::studyChanged( SUIT_Study* theStudy )
   PyLockWrapper aLock = myInterp->GetLockWrapper();
 
   // call Python module's activeStudyChanged() method
-  if ( PyObject_HasAttrString( myModule , "activeStudyChanged" ) ) {
-    PyObjWrapper res( PyObject_CallMethod( myModule, (char*)"activeStudyChanged", (char*)"i", aStudyId ) );
+  if ( PyObject_HasAttrString( myModule->get(), "activeStudyChanged" ) ) {
+    PyObjWrapper res( PyObject_CallMethod( myModule->get(), (char*)"activeStudyChanged", (char*)"i", aStudyId ) );
     if( !res ) {
       PyErr_Print();
     }
@@ -1150,10 +1154,10 @@ void SALOME_PYQT_ModuleLight::contextMenu( const QString& theContext, QMenu* the
 
   QString aContext( "" ), aObject( "" ), aParent( theContext );
 
-  if ( IsCallOldMethods && PyObject_HasAttrString( myModule , "definePopup" ) ) {
+  if ( IsCallOldMethods && PyObject_HasAttrString( myModule->get(), "definePopup" ) ) {
     // call definePopup() Python module's function
     // this is obsolete function, used only for compatibility reasons
-    PyObjWrapper res( PyObject_CallMethod( myModule,
+    PyObjWrapper res( PyObject_CallMethod( myModule->get(),
                                           (char*)"definePopup",
                                           (char*)"sss",
                                           theContext.toLatin1().constData(),
@@ -1181,8 +1185,8 @@ void SALOME_PYQT_ModuleLight::contextMenu( const QString& theContext, QMenu* the
   PyObjWrapper sipPopup( sipBuildResult( 0, "M", thePopupMenu, sipClass_QMenu ) );
 
   // then call Python module's createPopupMenu() method (for new modules)
-  if ( PyObject_HasAttrString( myModule , "createPopupMenu" ) ) {
-    PyObjWrapper res1( PyObject_CallMethod( myModule,
+  if ( PyObject_HasAttrString( myModule->get(), "createPopupMenu" ) ) {
+    PyObjWrapper res1( PyObject_CallMethod( myModule->get(),
                                            (char*)"createPopupMenu",
                                            (char*)"Os",
                                            sipPopup.get(),
@@ -1192,10 +1196,10 @@ void SALOME_PYQT_ModuleLight::contextMenu( const QString& theContext, QMenu* the
     }
   }
 
-  if ( IsCallOldMethods && PyObject_HasAttrString( myModule , "customPopup" ) ) {
+  if ( IsCallOldMethods && PyObject_HasAttrString( myModule->get(), "customPopup" ) ) {
     // call customPopup() Python module's function
     // this is obsolete function, used only for compatibility reasons
-    PyObjWrapper res2( PyObject_CallMethod( myModule,
+    PyObjWrapper res2( PyObject_CallMethod( myModule->get(),
                                            (char*)"customPopup",
                                            (char*)"Osss",
                                            sipPopup.get(),
@@ -1225,8 +1229,8 @@ void SALOME_PYQT_ModuleLight::guiEvent( const int theId )
   if ( !myInterp || !myModule )
     return;
 
-  if ( PyObject_HasAttrString( myModule , "OnGUIEvent" ) ) {
-    PyObjWrapper res( PyObject_CallMethod( myModule, (char*)"OnGUIEvent", (char*)"i", theId ) );
+  if ( PyObject_HasAttrString( myModule->get(), "OnGUIEvent" ) ) {
+    PyObjWrapper res( PyObject_CallMethod( myModule->get(), (char*)"OnGUIEvent", (char*)"i", theId ) );
     if( !res ) {
       PyErr_Print();
     }
@@ -1252,8 +1256,8 @@ void SALOME_PYQT_ModuleLight::initPreferences()
   // might be called during the module intialization process
   myInitModule = this;
 
-  if ( PyObject_HasAttrString( myModule , "createPreferences" ) ) {
-    PyObjWrapper res( PyObject_CallMethod( myModule, (char*)"createPreferences", (char*)"" ) );
+  if ( PyObject_HasAttrString( myModule->get(), "createPreferences" ) ) {
+    PyObjWrapper res( PyObject_CallMethod( myModule->get(), (char*)"createPreferences", (char*)"" ) );
     if( !res ) {
       PyErr_Print();
     }
@@ -1335,7 +1339,7 @@ void SALOME_PYQT_ModuleLight::importModule()
   PyLockWrapper aLock = myInterp->GetLockWrapper();
   // ... then import a module
   QString aMod = name() + "GUI";
-  myModule = PyImport_ImportModule( aMod.toLatin1().data() );
+  myModule = new PyObjWrapper( PyImport_ImportModule( aMod.toLatin1().data() ) );
   if( !myModule ) {
     // Error!
     PyErr_Print();
@@ -1388,8 +1392,8 @@ void SALOME_PYQT_ModuleLight::setWorkSpace()
     }
     PyObjWrapper pyws( sipBuildResult( 0, "M", aWorkspace, sipClass_QWidget ) );
     // ... and finally call Python module's setWorkspace() method (obsolete)
-    if ( PyObject_HasAttrString( myModule , "setWorkSpace" ) ) {
-      PyObjWrapper res( PyObject_CallMethod( myModule, (char*)"setWorkSpace", (char*)"O", pyws.get() ) );
+    if ( PyObject_HasAttrString( myModule->get(), "setWorkSpace" ) ) {
+      PyObjWrapper res( PyObject_CallMethod( myModule->get(), (char*)"setWorkSpace", (char*)"O", pyws.get() ) );
       if( !res ) {
         PyErr_Print();
       }
@@ -1415,8 +1419,8 @@ void SALOME_PYQT_ModuleLight::prefChanged( const QString& section, const QString
   if ( !myInterp || !myModule )
     return;
 
-  if ( PyObject_HasAttrString( myModule , "preferenceChanged" ) ) {
-    PyObjWrapper res( PyObject_CallMethod( myModule,
+  if ( PyObject_HasAttrString( myModule->get(), "preferenceChanged" ) ) {
+    PyObjWrapper res( PyObject_CallMethod( myModule->get(),
                                           (char*)"preferenceChanged", 
                                           (char*)"ss", 
                                           section.toLatin1().constData(), 
@@ -1813,12 +1817,12 @@ void SALOME_PYQT_ModuleLight::activeViewChanged( const SUIT_ViewWindow* pview )
   
   connectView( pview );
 
-  if ( PyObject_HasAttrString( myModule, "activeViewChanged" ) ) 
+  if ( PyObject_HasAttrString( myModule->get(), "activeViewChanged" ) ) 
   {
     if ( !pview ) 
       return;   
 
-    PyObjWrapper res( PyObject_CallMethod( myModule, (char*)"activeViewChanged", (char*)"i" , pview->getId() ) );
+    PyObjWrapper res( PyObject_CallMethod( myModule->get(), (char*)"activeViewChanged", (char*)"i" , pview->getId() ) );
     if( !res )
       PyErr_Print();
   }
@@ -1860,9 +1864,9 @@ void SALOME_PYQT_ModuleLight::viewCloned( const SUIT_ViewWindow* pview )
   if ( !myInterp || !myModule || !pview ) 
     return;  
 
-  if ( PyObject_HasAttrString( myModule, "viewCloned" ) ) 
+  if ( PyObject_HasAttrString( myModule->get(), "viewCloned" ) ) 
   {
-    PyObjWrapper res( PyObject_CallMethod( myModule, (char*)"viewCloned", (char*)"i", pview->getId() ) );
+    PyObjWrapper res( PyObject_CallMethod( myModule->get(), (char*)"viewCloned", (char*)"i", pview->getId() ) );
     if( !res )
       PyErr_Print();
   }
@@ -1904,9 +1908,9 @@ void SALOME_PYQT_ModuleLight::viewClosed( const SUIT_ViewWindow* pview )
   if ( !myInterp || !myModule ) 
     return;  
 
-  if ( PyObject_HasAttrString( myModule, "viewClosed" ) ) 
+  if ( PyObject_HasAttrString( myModule->get(), "viewClosed" ) ) 
   {
-    PyObjWrapper res( PyObject_CallMethod( myModule, (char*)"viewClosed", (char*)"i", pview->getId() ) );
+    PyObjWrapper res( PyObject_CallMethod( myModule->get(), (char*)"viewClosed", (char*)"i", pview->getId() ) );
     if ( !res )
     {
       PyErr_Print();
@@ -2372,8 +2376,8 @@ void SALOME_PYQT_ModuleLight::saveEvent(QStringList& theListOfFiles)
   if ( !myInterp || !myModule || (it == theListOfFiles.end()))
     return;
 
-  if ( PyObject_HasAttrString(myModule , "saveFiles") ) {
-    PyObjWrapper res( PyObject_CallMethod( myModule, (char*)"saveFiles",
+  if ( PyObject_HasAttrString(myModule->get(), "saveFiles") ) {
+    PyObjWrapper res( PyObject_CallMethod( myModule->get(), (char*)"saveFiles",
                                           (char*)"s", (*it).toLatin1().constData()));
     if( !res ) {
       PyErr_Print();
@@ -2451,8 +2455,8 @@ void SALOME_PYQT_ModuleLight::openEvent(QStringList theListOfFiles, bool &opened
 
   PyObjWrapper sipList( sipBuildResult( 0, "M", theList, sipClass_QStringList ) );
   
-  if ( PyObject_HasAttrString(myModule , "openFiles") ) {
-    PyObjWrapper res( PyObject_CallMethod( myModule, (char*)"openFiles",
+  if ( PyObject_HasAttrString(myModule->get() , "openFiles") ) {
+    PyObjWrapper res( PyObject_CallMethod( myModule->get(), (char*)"openFiles",
                                           (char*)"O", sipList.get()));
     if( !res || !PyBool_Check( res )) {
       PyErr_Print();
index 972788f691f5ccb6c2c6fbf8cb88f4d4bff5cf60..f9066c64075f2a158f42e0242bab4ffd3925a876 100644 (file)
@@ -63,7 +63,7 @@ private:
   bool                       myLastActivateStatus; //!< latest module activation status
 
 protected:
-  PyObjWrapper                    myModule;     //!< Python GUI module
+  PyObjWrapper*                   myModule;     //!< Python GUI module
   PyInterp_Interp*                myInterp;     //!< current Python subinterpreter
   static InterpMap                myInterpMap;  //!< study to Python subinterpreter map