]> SALOME platform Git repositories - modules/gui.git/commitdiff
Salome HOME
Porting Python side of the tool.
authorabn <adrien.bruneton@cea.fr>
Tue, 15 Jan 2019 13:24:23 +0000 (14:24 +0100)
committerabn <adrien.bruneton@cea.fr>
Wed, 16 Jan 2019 12:40:53 +0000 (13:40 +0100)
35 files changed:
tools/CurvePlot/CMakeLists.txt
tools/CurvePlot/SalomeCURVEPLOTConfig.cmake.in
tools/CurvePlot/src/cpp/test/CMakeLists.txt
tools/CurvePlot/src/python/controller/CMakeLists.txt
tools/CurvePlot/src/python/controller/PlotController.py
tools/CurvePlot/src/python/controller/__init__.py
tools/CurvePlot/src/python/controller/utils.py.in
tools/CurvePlot/src/python/model/CMakeLists.txt
tools/CurvePlot/src/python/model/CurveModel.py
tools/CurvePlot/src/python/model/PlotManager.py
tools/CurvePlot/src/python/model/TableModel.py
tools/CurvePlot/src/python/model/XYPlotSetModel.py
tools/CurvePlot/src/python/pyqtside/CMakeLists.txt
tools/CurvePlot/src/python/pyqtside/QtCore.py
tools/CurvePlot/src/python/pyqtside/QtGui.py
tools/CurvePlot/src/python/pyqtside/QtWidgets.py [new file with mode: 0644]
tools/CurvePlot/src/python/pyqtside/__init__.py
tools/CurvePlot/src/python/pyqtside/pyside_dynamic.py
tools/CurvePlot/src/python/pyqtside/uic.py
tools/CurvePlot/src/python/test/CMakeLists.txt
tools/CurvePlot/src/python/test/PlotCurve_Standalone.py
tools/CurvePlot/src/python/test/PlotTestBase.py
tools/CurvePlot/src/python/test/README.txt
tools/CurvePlot/src/python/test/SalomePyQt_MockUp.py.in
tools/CurvePlot/src/python/test/TestDesktop.py
tools/CurvePlot/src/python/test/plot_test.py
tools/CurvePlot/src/python/ui/CMakeLists.txt
tools/CurvePlot/src/python/ui/CurveTreeDockWidget.py
tools/CurvePlot/src/python/ui/PlotSettings.py
tools/CurvePlot/src/python/ui/PlotWidget.py
tools/CurvePlot/src/python/views/CMakeLists.txt
tools/CurvePlot/src/python/views/CurveBrowserView.py
tools/CurvePlot/src/python/views/CurveTabsView.py
tools/CurvePlot/src/python/views/CurveView.py
tools/CurvePlot/src/python/views/XYView.py

index 41cd1dc67518f3b4e9f13f9c41bab77807cd542b..6794d4563a919656fd35b7e328a136f2b29ec12a 100755 (executable)
@@ -29,12 +29,12 @@ CMAKE_POLICY(SET CMP0003 NEW)
 # Project name, upper case
 STRING(TOUPPER ${PROJECT_NAME} PROJECT_NAME_UC)
 
-SET(${PROJECT_NAME_UC}_MAJOR_VERSION 7)
-SET(${PROJECT_NAME_UC}_MINOR_VERSION 6)
+SET(${PROJECT_NAME_UC}_MAJOR_VERSION 9)
+SET(${PROJECT_NAME_UC}_MINOR_VERSION 2)
 SET(${PROJECT_NAME_UC}_PATCH_VERSION 0)
 SET(${PROJECT_NAME_UC}_VERSION
   ${${PROJECT_NAME_UC}_MAJOR_VERSION}.${${PROJECT_NAME_UC}_MINOR_VERSION}.${${PROJECT_NAME_UC}_PATCH_VERSION})
-SET(${PROJECT_NAME_UC}_VERSION_DEV 1)
+SET(${PROJECT_NAME_UC}_VERSION_DEV 0)
 
 # User options
 # ============
@@ -106,20 +106,11 @@ FIND_PACKAGE(SalomePythonInterp    REQUIRED)
 FIND_PACKAGE(SalomePythonLibs    REQUIRED)
 FIND_PACKAGE(SalomeNumPySciPy    REQUIRED)
 
-# Qt4
-FIND_PACKAGE(SalomeQt4 REQUIRED COMPONENTS QtCore QtGui)
-INCLUDE(${QT_USE_FILE})
+# Qt
+FIND_PACKAGE(SalomeQt5 REQUIRED)
+FIND_PACKAGE(SalomePyQt5 REQUIRED)
 
 # Optional products:
-
-IF(SALOME_BUILD_DOC)
-#  FIND_PACKAGE(SalomeDoxygen)
-#  FIND_PACKAGE(SalomeSphinx)
-#  SALOME_LOG_OPTIONAL_PACKAGE(Doxygen SALOME_BUILD_DOC)
-#  SALOME_LOG_OPTIONAL_PACKAGE(Sphinx SALOME_BUILD_DOC)
-#  ADD_DEFINITIONS(-DDOXYGEN_IS_OK)
-ENDIF()
-
 IF(SALOME_BUILD_TESTS)
   ENABLE_TESTING()
 ENDIF()
@@ -155,12 +146,15 @@ ENDIF()
 # Specific to CURVEPLOT:
 SET(SALOME_CURVEPLOT_INSTALL_RES_DATA "${SALOME_INSTALL_RES}/curveplot" CACHE PATH 
     "Install path: SALOME CURVEPLOT specific data")
-# Package installation path (lib/python2.7/...) 
+# Package installation path (lib/python<x.y>/...)
 SET(SALOME_CURVEPLOT_INSTALL_PYTHON ${SALOME_INSTALL_PYTHON}/curveplot CACHE INTERNAL  
     "Install path: SALOME CURVEPLOT Python packages" FORCE)
 SET(SALOME_CURVEPLOT_INSTALL_SCRIPT_PYTHON ${SALOME_INSTALL_SCRIPT_PYTHON} CACHE INTERNAL  
     "Install path: SALOME CURVEPLOT Python main entry points" FORCE)
 
+SET(CRVPLOT_TEST_INSTALL ${CMAKE_BINARY_DIR}/local/curveplot)
+SET(PYQTSIDE_TEST_INSTALL ${CMAKE_BINARY_DIR}/local/pyqtside)
+
 # Sources 
 # ========
 ADD_SUBDIRECTORY(src)
@@ -192,25 +186,25 @@ EXPORT(TARGETS ${_${PROJECT_NAME}_exposed_targets}
 #      Ensure the variables are always defined for the configure:
 SET(KERNEL_ROOT_DIR "${KERNEL_ROOT_DIR}")
 SET(GUI_ROOT_DIR "${GUI_ROOT_DIR}")
-SET(QT4_ROOT_DIR "${QT4_ROOT_DIR}")
-SET(PYQT4_ROOT_DIR "${PYQT4_ROOT_DIR}")
+SET(QT5_ROOT_DIR "${QT5_ROOT_DIR}")
+SET(PYQT5_ROOT_DIR "${PYQT5_ROOT_DIR}")
 SET(PYTHON_ROOT_DIR "${PYTHON_ROOT_DIR}")
  
 SET(CONF_INCLUDE_DIRS "${PROJECT_SOURCE_DIR}/include" "${PROJECT_BINARY_DIR}/include")
 
 # Build variables that will be expanded when configuring Salome<MODULE>Config.cmake:
-SALOME_CONFIGURE_PREPARE(PyQt4 Qt4 Python)
+SALOME_CONFIGURE_PREPARE(PyQt5 Qt5 Python)
 
 CONFIGURE_PACKAGE_CONFIG_FILE(${PROJECT_NAME}Config.cmake.in 
     ${PROJECT_BINARY_DIR}/${PROJECT_NAME}Config.cmake
     INSTALL_DESTINATION "${SALOME_INSTALL_CMAKE_LOCAL}"
     PATH_VARS CONF_INCLUDE_DIRS SALOME_INSTALL_CMAKE_LOCAL CMAKE_INSTALL_PREFIX
-       KERNEL_ROOT_DIR GUI_ROOT_DIR QT4_ROOT_DIR PYQT4_ROOT_DIR PYTHON_ROOT_DIR)
+       KERNEL_ROOT_DIR GUI_ROOT_DIR QT5_ROOT_DIR PYQT5_ROOT_DIR PYTHON_ROOT_DIR)
 
 WRITE_BASIC_PACKAGE_VERSION_FILE(${PROJECT_BINARY_DIR}/${PROJECT_NAME}ConfigVersion.cmake
     VERSION ${${PROJECT_NAME_UC}_VERSION}
     COMPATIBILITY AnyNewerVersion)
-  
+
 # Install the CMake configuration files:
 INSTALL(FILES
   "${PROJECT_BINARY_DIR}/${PROJECT_NAME}Config.cmake"
@@ -222,4 +216,4 @@ IF(NOT SALOME_CURVEPLOT_STANDALONE)
     INSTALL(EXPORT ${PROJECT_NAME}TargetGroup DESTINATION "${SALOME_INSTALL_CMAKE_LOCAL}" 
         FILE ${PROJECT_NAME}Targets.cmake)
 ENDIF()
-  
+
index 76b16dda86ee11a223721c7cf65de2c328d002db..cb08b646bc20474aa56a15598aa2bd403b86b575 100644 (file)
@@ -53,8 +53,8 @@ IF(SALOME_CURVEPLOT_STANDALONE)
   SET_AND_CHECK(GUI_ROOT_DIR_EXP "@PACKAGE_GUI_ROOT_DIR@")
 ENDIF()
 
-SET_AND_CHECK(QT4_ROOT_DIR_EXP "@PACKAGE_QT4_ROOT_DIR@")
-SET_AND_CHECK(PYQT4_ROOT_DIR_EXP "@PACKAGE_PYQT4_ROOT_DIR@")
+SET_AND_CHECK(QT5_ROOT_DIR_EXP "@PACKAGE_QT5_ROOT_DIR@")
+SET_AND_CHECK(PYQT5_ROOT_DIR_EXP "@PACKAGE_PYQT5_ROOT_DIR@")
 SET_AND_CHECK(PYTHON_ROOT_DIR_EXP "@PACKAGE_PYTHON_ROOT_DIR@")
 
 
index 17e1c157acb87ed38c7bde9e46445050ab8938c1..de36b3ec69848d096070afab0a8ada287e235446 100755 (executable)
@@ -44,7 +44,7 @@ SET(_other_SOURCES
 # --- rules ---
 
 # sources / moc wrappings
-QT4_WRAP_CPP(_moc_SOURCES ${_moc_HEADERS})
+QT5_WRAP_CPP(_moc_SOURCES ${_moc_HEADERS})
 
 ADD_EXECUTABLE(test_curveplot ${_other_SOURCES} ${_moc_SOURCES})
 TARGET_LINK_LIBRARIES(test_curveplot ${_link_LIBRARIES})
index 1c51e37f5d22f431e6b2ddbae54c0a87b03c6113..241c0e76a703324a6e0c779b4aba2b270c248be3 100644 (file)
 # See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 #
 
+SET(SALOME_CURVEPLOT_TEST_MODE "0")
 SALOME_CONFIGURE_FILE(utils.py.in ${CMAKE_CURRENT_BINARY_DIR}/utils.py)
 
+# For test purposes:
+SET(SALOME_CURVEPLOT_TEST_MODE "1")
+SALOME_CONFIGURE_FILE(utils.py.in ${CMAKE_CURRENT_BINARY_DIR}/utils_test.py)
+SET(SALOME_CURVEPLOT_TEST_MODE "0")
+
 SET(_all_lib_SCRIPTS
     PlotController.py
     __init__.py
-    ${CMAKE_CURRENT_BINARY_DIR}/utils.py
 )
 
+SET(_util_SCRIPT ${CMAKE_CURRENT_BINARY_DIR}/utils.py)
+
 SALOME_INSTALL_SCRIPTS("${_all_lib_SCRIPTS}" ${SALOME_CURVEPLOT_INSTALL_PYTHON})
+SALOME_INSTALL_SCRIPTS("${_util_SCRIPT}" ${SALOME_CURVEPLOT_INSTALL_PYTHON})
+
+# For test purposes
+FILE(COPY ${_all_lib_SCRIPTS} DESTINATION ${CRVPLOT_TEST_INSTALL})
+FILE(COPY ${CMAKE_CURRENT_BINARY_DIR}/utils_test.py DESTINATION ${CRVPLOT_TEST_INSTALL})
+FILE(RENAME ${CRVPLOT_TEST_INSTALL}/utils_test.py ${CRVPLOT_TEST_INSTALL}/utils.py)
index f5670e52ed421de823adfb4d4897269054903ea7..5122b61e2a8103975686152dd3182521afa6db8e 100644 (file)
@@ -1,20 +1,20 @@
-from CurveBrowserView import CurveBrowserView
-from PlotManager import PlotManager
-from CurveTabsView import CurveTabsView
-from CurveModel import CurveModel
-from TableModel import TableModel
-from utils import Logger
+from .CurveBrowserView import CurveBrowserView
+from .PlotManager import PlotManager
+from .CurveTabsView import CurveTabsView
+from .CurveModel import CurveModel
+from .TableModel import TableModel
+from .utils import Logger
 import numpy as np
 
 class PlotController(object):
   """ Controller for 2D curve plotting functionalities.
   """
   __UNIQUE_INSTANCE = None  # my poor impl. of a singleton
-  
+
   ## For testing purposes:
   WITH_CURVE_BROWSER = True
   WITH_CURVE_TABS = True
-  
+
   def __init__(self, sgPyQt=None):
     if self.__UNIQUE_INSTANCE is None:
       self.__trueInit(sgPyQt)
@@ -31,32 +31,32 @@ class PlotController(object):
     self._blockNotifications = False
     self._blockViewClosing = False
     self._callbacks = []
-    
+
     self._plotManager = PlotManager(self)
-    
+
     if self.WITH_CURVE_BROWSER:
       self._curveBrowserView = CurveBrowserView(self)
       self.associate(self._plotManager, self._curveBrowserView)
     else:
-      self._curveBrowserView = None  
+      self._curveBrowserView = None
     if self.WITH_CURVE_TABS:
       self._curveTabsView = CurveTabsView(self)
       self.associate(self._plotManager, self._curveTabsView)
     else:
       self._curveTabsView = None
     PlotController.__UNIQUE_INSTANCE = self
-  
+
   @classmethod
   def GetInstance(cls, sgPyQt=None):
     if cls.__UNIQUE_INSTANCE is None:
       # First instanciation:
       PlotController(sgPyQt)
     return cls.__UNIQUE_INSTANCE
-  
+
   @classmethod
   def Destroy(cls):
     cls.__UNIQUE_INSTANCE = None
-  
+
   def setFixedSizeWidget(self):
     """ For testing purposes - ensure visible Qt widgets have a fixed size.
     """
@@ -64,7 +64,7 @@ class PlotController(object):
       self._curveBrowserView.treeWidget.resize(100,200)
     if self.WITH_CURVE_TABS:
       self._sgPyQt._tabWidget.resize(600,600)
-  
+
   def associate(self, model, view):
     """
     Associates a model to a view, and sets the view to listen to this model 
@@ -73,28 +73,28 @@ class PlotController(object):
     :param model: Model -- The model to be associated to the view.
     :param view: View -- The view.
     
-    """    
+    """
     if model is None or view is None:
         return
-  
+
     view.setModel(model)
     self.setModelListener(model, view)
-  
+
   def setModelListener(self, model, view):
     """
     Sets a view to listen to all changes of the given model
     """
     l = self._modelViews.setdefault(model, [])
     if not view in l and view is not None:
-      l.append(view) 
-  
+      l.append(view)
+
   def removeModelListeners(self, model):
     """ 
     Removes the given model from the list of listeners. All views previously connected to this model
     won't receive its update notification anymore.
     """
     self._modelViews.pop(model)
-  
+
   def notify(self, model, what=""):
     """
     Notifies the view when model changes.
@@ -103,10 +103,10 @@ class PlotController(object):
     """
     if model is None or self._blockNotifications:
       return
-    
+
     if model not in self._modelViews:
       return
-    
+
     for view in self._modelViews[model]:
       method = "on%s" % what
       if what != "" and what is not None and hasattr(view, method):
@@ -114,27 +114,27 @@ class PlotController(object):
       elif hasattr(view, "update"):
         # Generic update:
         view.update()
-    
+
   def setBrowserContextualMenu(self, menu):
     """ Provide a menu to be contextually shown in the curve browser """
     self._browserContextualMenu = menu
-    
+
   def setCurvePlotRequestingClose(self, bool):
     self._blockViewClosing = bool
-    
+
   def onCurrentCurveChange(self):
     ps = self._plotManager.getCurrentPlotSet()
     if not ps is None:
       crv = ps.getCurrentCurve()
       if crv is not None:
-        crv_id = crv.getID() 
+        crv_id = crv.getID()
         for c in self._callbacks:
           c(crv_id)
-    
+
   #####
   ##### Public static API
   #####
-  
+
   @classmethod
   def AddCurve(cls, x, y, curve_label="", x_label="", y_label="", append=True):
     """ Add a new curve and make the plot set where it is drawn the active one.
@@ -148,7 +148,7 @@ class PlotController(object):
         @param append whether to add the curve to the active plot set (default) or into a new one.
         @return the id of the created curve, and the id of the corresponding plot set.
     """
-    from XYView import XYView
+    from .XYView import XYView
     control = cls.GetInstance()
     pm = control._plotManager
     t = TableModel(control)
@@ -158,18 +158,18 @@ class PlotController(object):
     prevLock = pm.isRepaintLocked()
     if not prevLock:
       pm.lockRepaint()
-    curveID, plotSetID = control.plotCurveFromTable(t, x_col_index=0, y_col_index=1, 
+    curveID, plotSetID = control.plotCurveFromTable(t, x_col_index=0, y_col_index=1,
                                                     curve_label=curve_label, append=append)
     ps = pm._plotSets[plotSetID]
     if x_label != "":
       ps.setXLabel(x_label)
-    if y_label != "": 
+    if y_label != "":
       ps.setYLabel(y_label)
     if not prevLock:
       pm.unlockRepaint()
     return curveID, plotSetID
 
-  @classmethod  
+  @classmethod
   def ExtendCurve(cls, crv_id, x, y):
     """ Add new points to an already created curve
     @raise if invalid plot set ID is given
@@ -181,7 +181,7 @@ class PlotController(object):
     crv_mod = ps._curves[crv_id]
     data = np.transpose(np.vstack([x, y]))
     crv_mod.extendData(data)
-    
+
   @classmethod
   def ResetCurve(cls, crv_id):
     """ Reset a given curve: all data are cleared, but the curve is still 
@@ -195,7 +195,7 @@ class PlotController(object):
       raise ValueError("Curve ID (%d) not found for reset!" % crv_id)
     crv_mod = ps._curves[crv_id]
     crv_mod.resetData()
-    
+
   @classmethod
   def AddPlotSet(cls, title=""):
     """ Creates a new plot set (a tab with several curves) and returns its ID. A title can be passed,
@@ -210,7 +210,7 @@ class PlotController(object):
     if title != "":
       ps.setTitle(title)
     return ps.getID()
-            
+
   @classmethod
   def CopyCurve(cls, curve_id, plot_set_id):
     """ Copy a given curve to a given plot set ID
@@ -229,7 +229,7 @@ class PlotController(object):
     control.setModelListener(new_crv, control._curveBrowserView)
     plot_set_tgt.addCurve(new_crv)
     return new_crv.getID()
-      
+
   @classmethod
   def DeleteCurve(cls, curve_id=-1):
     """ By default, delete the current curve, if any. Otherwise do nothing.
@@ -242,8 +242,8 @@ class PlotController(object):
       curve_id = cls.GetCurrentCurveID()
       if curve_id == -1:
         # No current curve, do nothing
-        return -1 
-      
+        return -1
+
     psID = cls.GetPlotSetID(curve_id)
     if psID == -1:
       raise ValueError("Curve ID (%d) not found for deletion!" % curve_id)
@@ -251,7 +251,7 @@ class PlotController(object):
     control._plotManager._plotSets[psID].removeCurve(curve_id)
     control.removeModelListeners(crv)
     return curve_id
-  
+
   @classmethod
   def DeletePlotSet(cls, plot_set_id=-1):
     """ By default, delete the current plot set, if any. Otherwise do nothing.
@@ -271,11 +271,11 @@ class PlotController(object):
     for _, crv in list(ps._curves.items()):
       control.removeModelListeners(crv)
     control.removeModelListeners(ps)
-    psets = control._plotManager._plotSets 
+    psets = control._plotManager._plotSets
     if len(psets):
       control._plotManager.setCurrentPlotSet(list(psets.keys())[-1])
     return plot_set_id
-  
+
   @classmethod
   def usedMem(cls):
       import gc
@@ -283,7 +283,7 @@ class PlotController(object):
       import resource
       m = resource.getrusage(resource.RUSAGE_SELF)[2]*resource.getpagesize()/1e6
       print("** Used memory: %.2f Mb" % m)
-  
+
   @classmethod
   def DeleteCurrentItem(cls):
     """ Delete currently active item, be it a plot set or a curve.
@@ -296,7 +296,7 @@ class PlotController(object):
     if ps_id == -1:
       Logger.Info("PlotController.DeleteCurrentItem(): nothing selected, nothing to delete!")
       return True,-1
-    # Do we delete a curve or a full plot set    
+    # Do we delete a curve or a full plot set
     if c_id == -1:
       cls.DeletePlotSet(ps_id)
       ret = True, ps_id
@@ -304,7 +304,7 @@ class PlotController(object):
       cls.DeleteCurve(c_id)
       ret = False, c_id
     return ret
-  
+
   @classmethod
   def ClearPlotSet(cls, ps_id=-1):
     """ Clear all curves in a given plot set. By default clear the current plot set without deleting it,
@@ -322,7 +322,7 @@ class PlotController(object):
       raise ValueError("Invalid plot set ID (%d)!" % ps_id)
     ps.eraseAll()
     return ps_id
-  
+
 #   @classmethod
 #   def ClearAll(cls):
 #     # TODO: optimize
@@ -330,7 +330,7 @@ class PlotController(object):
 #     ids = pm._plotSets.keys()
 #     for i in ids:
 #       cls.DeletePlotSet(i)
-  
+
   @classmethod
   def SetXLabel(cls, x_label, plot_set_id=-1):
     """  By default set the X axis label for the current plot set, if any. Otherwise do nothing.
@@ -341,14 +341,14 @@ class PlotController(object):
       plot_set_id = cls.GetCurrentPlotSetID()
       if plot_set_id == -1:
         # Do nothing
-        return False 
+        return False
     ps = pm._plotSets.get(plot_set_id, None)
     if ps is None:
       raise Exception("Invalid plot set ID (%d)!" % plot_set_id)
     ps.setXLabel(x_label)
     return True
-     
-  @classmethod 
+
+  @classmethod
   def SetYLabel(cls, y_label, plot_set_id=-1):
     """ By default set the Y axis label for the current plot set, if any. Otherwise do nothing.
          @return True if the label was set
@@ -358,14 +358,14 @@ class PlotController(object):
       plot_set_id = cls.GetCurrentPlotSetID()
       if plot_set_id == -1:
         # Do nothing
-        return False 
+        return False
     ps = pm._plotSets.get(plot_set_id, None)
     if ps is None:
       raise Exception("Invalid plot set ID (%d)!" % plot_set_id)
     ps.setYLabel(y_label)
     return True
-     
-  @classmethod 
+
+  @classmethod
   def SetPlotSetTitle(cls, title, plot_set_id=-1):
     """ By default set the title for the current plot set, if any. Otherwise do nothing.
          @return True if the title was set
@@ -375,13 +375,13 @@ class PlotController(object):
       plot_set_id = cls.GetCurrentPlotSetID()
       if plot_set_id == -1:
         # Do nothing
-        return False 
+        return False
     ps = pm._plotSets.get(plot_set_id, None)
     if ps is None:
       raise Exception("Invalid plot set ID (%d)!" % plot_set_id)
     ps.setTitle(title)
     return True
-  
+
   @classmethod
   def GetPlotSetID(cls, curve_id):
     """ @return plot set id for a given curve or -1 if invalid curve ID
@@ -391,17 +391,17 @@ class PlotController(object):
     if cps is None:
       return -1
     return cps.getID()
-  
+
   @classmethod
   def GetPlotSetIDByName(cls, name):
     """ @return the first plot set whose name matches the provided name. Otherwise returns -1
-    """ 
+    """
     pm = cls.GetInstance()._plotManager
     for _, ps in list(pm._plotSets.items()):
       if ps._title == name:
         return ps.getID()
     return -1
-  
+
   @classmethod
   def GetAllPlotSets(cls):
     """ @return two lists: plot set names, and corresponding plot set IDs
@@ -409,12 +409,12 @@ class PlotController(object):
     pm = cls.GetInstance()._plotManager
     it = list(pm._plotSets.items())
     ids, inst, titles = [], [], []
-    if len(it):  
-      ids, inst = list(zip(*it))        
+    if len(it):
+      ids, inst = list(zip(*it))
     if len(inst):
       titles = [i.getTitle() for i in inst]
     return list(ids), titles
-  
+
   @classmethod
   def GetCurrentCurveID(cls):
     """ @return current curve ID or -1 if no curve is currently active
@@ -424,8 +424,8 @@ class PlotController(object):
     if crv is None:
       return -1
     return crv.getID()
-     
-  @classmethod   
+
+  @classmethod
   def GetCurrentPlotSetID(cls):
     """ @return current plot set ID or -1 if no plot set is currently active
     """
@@ -433,7 +433,7 @@ class PlotController(object):
     cps = control._plotManager.getCurrentPlotSet()
     if cps is None:
       return -1
-    return cps.getID()  
+    return cps.getID()
 
   @classmethod
   def SetCurrentPlotSet(cls, ps_id):
@@ -470,7 +470,7 @@ class PlotController(object):
     if cls.__UNIQUE_INSTANCE is not None:
       raise Exception("ToggleCurveBrowser() must be invoked before doing anything in plot2D!")
     cls.WITH_CURVE_BROWSER = active
-    
+
   @classmethod
   def IsValidPlotSetID(cls, plot_set_id):
     """ 
@@ -529,11 +529,11 @@ class PlotController(object):
                    ]
     @raise if invalid curve ID or marker
     """
-    from XYView import XYView
-    from CurveView import CurveView
+    from .XYView import XYView
+    from .CurveView import CurveView
     if not marker in XYView.CURVE_MARKERS:
       raise ValueError("Invalid marker: '%s'" % marker)
-    
+
     cont = cls.GetInstance()
     for mod, views in list(cont._modelViews.items()):
       if isinstance(mod, CurveModel) and mod.getID() == crv_id:
@@ -544,7 +544,7 @@ class PlotController(object):
             v._parentXYView.repaint()
             v._parentXYView.showHideLegend()
             found = True
-        
+
     if not found:
       raise Exception("Invalid curve ID or curve currently not displayed (curve_id=%d)!" % crv_id)
 
@@ -562,9 +562,9 @@ class PlotController(object):
   @classmethod
   def __XYViewOperation(cls, func, ps_id, args, kwargs):
     """ Private. To factorize methods accessing the XYView to change a display element. """
-    from XYPlotSetModel import XYPlotSetModel
-    from XYView import XYView
-    
+    from .XYPlotSetModel import XYPlotSetModel
+    from .XYView import XYView
+
     cont = cls.GetInstance()
     for mod, views in list(cont._modelViews.items()):
       if isinstance(mod, XYPlotSetModel) and mod.getID() == ps_id:
@@ -595,7 +595,7 @@ class PlotController(object):
     """
     args, kwargs = [log], {}
     cls.__XYViewOperation("setYLog", ps_id, args, kwargs)
-     
+
   @classmethod
   def SetXSciNotation(cls, ps_id, sciNotation=False):
     """ Change the format (scientific notation or not) of the X axis.
@@ -605,7 +605,7 @@ class PlotController(object):
     """
     args, kwargs = [sciNotation], {}
     cls.__XYViewOperation("setXSciNotation", ps_id, args, kwargs)
-   
+
   @classmethod
   def SetYSciNotation(cls, ps_id, sciNotation=False):
     """ Change the format (scientific notation or not) of the Y axis.
@@ -625,7 +625,7 @@ class PlotController(object):
     """
     args, kwargs = [visible], {}
     cls.__XYViewOperation("setLegendVisible", ps_id, args, kwargs)
-    
+
 
   ###
   ### More advanced functions
@@ -634,28 +634,28 @@ class PlotController(object):
   def RegisterCallback(cls, callback):
     cont = cls.GetInstance()
     cont._callbacks.append(callback)
-  
+
   @classmethod
   def ClearCallbacks(cls):
     cont = cls.GetInstance()
     cont._callbacks = []
-  
+
   @classmethod
   def LockRepaint(cls):
     control = cls.GetInstance()
     control._plotManager.lockRepaint()
-  
+
   @classmethod
   def UnlockRepaint(cls):
     control = cls.GetInstance()
-    control._plotManager.unlockRepaint()  
-  
+    control._plotManager.unlockRepaint()
+
   def createTable(self, data, table_name="table"):
     t = TableModel(self)
     t.setData(data)
     t.setTitle(table_name)
     return t
-     
+
   def plotCurveFromTable(self, table, x_col_index=0, y_col_index=1, curve_label="", append=True):
     """
     :returns: a tuple containing the unique curve ID and the plot set ID 
@@ -671,15 +671,15 @@ class PlotController(object):
       cps_title = None
 
     cps = self._plotManager.getCurrentPlotSet()
-    
+
     cm = CurveModel(self, table, y_col_index)
     cm.setXAxisIndex(x_col_index)
-    
+
     # X axis label
     tix = table.getColumnTitle(x_col_index)
     if tix != "":
       cps.setXLabel(tix)
-    
+
     # Curve label
     if curve_label != "":
       cm.setTitle(curve_label)
@@ -690,21 +690,21 @@ class PlotController(object):
 
     # Plot set title
     if cps_title != "" and cps_title is not None:
-      Logger.Debug("about to set title to: " + cps_title)  
+      Logger.Debug("about to set title to: " + cps_title)
       cps.setTitle(cps_title)
-    
+
     cps.addCurve(cm)
     mp = self._curveTabsView.mapModId2ViewId()
     xyview_id = mp[cps.getID()]
     xyview = self._curveTabsView._XYViews[xyview_id]
-    
+
     if cps_title is None:  # no plot set was created above
       self._plotManager.setCurrentPlotSet(cps.getID())
-      
+
     # Make CurveBrowser and CurveView depend on changes in the curve itself:
     self.setModelListener(cm, self._curveBrowserView)
     self.setModelListener(cm, xyview._curveViews[cm.getID()])
     # Upon change on the curve also update the full plot, notably for the auto-fit and the legend:
     self.setModelListener(cm, xyview)
-        
+
     return cm.getID(),cps.getID()
index 62d412f2d632bb892c6ba1a46c09a5c2392f994b..a92f4d6ca1c0f61523a34297434e1afe4350e25a 100644 (file)
@@ -6,19 +6,19 @@ try:
   # and the Bitstream font which is the first one by default. Try to use DejaVu which is more 
   # comprehensive.
   ## !!Order of the sequence below is highly sensitive!!
-  import pyqtside   # will trigger the PySide/PyQt4 switch
+  import pyqtside   # will trigger the PySide/PyQt switch
   import matplotlib
-  matplotlib.use('Qt4Agg')
-  import matplotlib.pyplot as plt  # must come after the PySide/PyQt4 switch!
+  matplotlib.use('Qt5Agg')
+  import matplotlib.pyplot as plt  # must come after the PySide/PyQt switch!
   plt.rcParams['font.sans-serif'].insert(0, "DejaVu Sans")
 except:
-  print("Warning: could not switch matplotlib to 'Qt4agg' backend. Some characters might be displayed improperly!")
+  print("Warning: could not switch matplotlib to 'Qt5agg' backend. Some characters might be displayed improperly!")
 
 from .PlotController import PlotController
-from TableModel import TableModel
-from CurveModel import CurveModel
-from PlotManager import PlotManager
-from XYPlotSetModel import XYPlotSetModel
+from .TableModel import TableModel
+from .CurveModel import CurveModel
+from .PlotManager import PlotManager
+from .XYPlotSetModel import XYPlotSetModel
 
 ## The static API of PlotController is the main interface of the package and is hence exposed at package level:
 AddCurve = PlotController.AddCurve
index 684858174ef83b5b2aae16de2e57d52cb7cea9bd..f4225711ab7e0c173f0d082cb847ac50d0ea804d 100644 (file)
@@ -59,20 +59,20 @@ class Logger(object):
       
 def trQ(tag, context="CURVEPLOT"):
   """ @return a QString read from the translation file """
-  from pyqtside.QtGui import QApplication 
+  from pyqtside.QtWidgets import QApplication 
   return QApplication.translate(context, tag) 
 
 def trU(tag, context="CURVEPLOT"):
   """ @return same as above, but returns a Python unicode string.  """
   qs = trQ(tag, context)
-  return unicode(qs, 'utf-8')
+  return str(qs, 'utf-8')
 
 def toUnicodeWithWarning(s, method_name):
   try: 
-    s = unicode(s)
+    s = str(s)
   except:
     Logger.Warning("%s - warning, passing non-unicode, non-ASCII string '%s'! Trying to convert myself to UTF-8 ..." % (method_name, s))
-    s = unicode(s, 'utf-8')
+    s = str(s, 'utf-8')
   return s
 
 def completeResPath(fileName):
@@ -81,5 +81,7 @@ def completeResPath(fileName):
   rd = os.environ.get("CURVEPLOT_ROOT_DIR", None)
   if rd is None:
     raise Exception("CURVEPLOT_ROOT_DIR is not defined!")
+  if @SALOME_CURVEPLOT_TEST_MODE@:   # do not remove automatically modified in CMake config
+    subPath = "@CRVPLOT_TEST_INSTALL@"
   filePath = os.path.join(rd, subPath, fileName)
   return filePath
index 964d05ebfa30eb8821528bb4a5b00532ba1c3b4f..64db612c6ea7a2825b656afd9688fd44578e87eb 100644 (file)
@@ -24,5 +24,8 @@ SET(_all_lib_SCRIPTS
     PlotManager.py
     XYPlotSetModel.py
 )
-    
+
 SALOME_INSTALL_SCRIPTS("${_all_lib_SCRIPTS}" ${SALOME_CURVEPLOT_INSTALL_PYTHON})
+
+# For test purposes
+FILE(COPY ${_all_lib_SCRIPTS} DESTINATION ${CRVPLOT_TEST_INSTALL})
index c111796792e5b7328ad78d0dd36cda57e8eb0d79..d426f6906f7dfc2a9a7d13b31149c1375c23205f 100644 (file)
@@ -1,5 +1,5 @@
-from Model import Model
-from utils import toUnicodeWithWarning
+from .Model import Model
+from .utils import toUnicodeWithWarning
 
 class CurveModel(Model):  
   def __init__(self, controller, table=None, index=-1):
index b874737e0dd62ee2de7608ef4b35e7a8e46889dd..45c665d2d5bfcd1189249ad9889c884d12cc2793 100644 (file)
@@ -1,6 +1,6 @@
-from Model import Model
-from XYPlotSetModel import XYPlotSetModel
-from utils import Logger
+from .Model import Model
+from .XYPlotSetModel import XYPlotSetModel
+from .utils import Logger
 
 class PlotManager(Model):
   def __init__(self, controller):
index 2f30aa7db95eed54b5cf9bd58fc1685876283995..11600e7b3612ff5cd0a40a1b2451998d7dda4a15 100644 (file)
@@ -1,6 +1,6 @@
 import numpy as np
-from Model import Model
-from utils import toUnicodeWithWarning, Logger
+from .Model import Model
+from .utils import toUnicodeWithWarning, Logger
 
 class TableModel(Model):
   def __init__(self, controller):
index 2edacfb9e14918cc06a73fb3fbddaf614d15c37a..9d29b98b39a6a6006553917f8172f3f75c6dabaa 100644 (file)
@@ -1,5 +1,5 @@
-from Model import Model
-from utils import toUnicodeWithWarning
+from .Model import Model
+from .utils import toUnicodeWithWarning
 
 class XYPlotSetModel(Model):
   
index 9ec5d8758a52e114097a6a0487373ef1e01fdae6..2ad9e4faa0d6dfd040ce796dae728cc0fbe388dd 100644 (file)
@@ -21,8 +21,12 @@ SET(_pyqtside_SCRIPTS
     __init__.py
     QtCore.py
     QtGui.py
+    QtWidgets.py
     pyside_dynamic.py
     uic.py
 )
 
 SALOME_INSTALL_SCRIPTS("${_pyqtside_SCRIPTS}" ${SALOME_INSTALL_PYTHON}/pyqtside)
+
+# For test purposes
+FILE(COPY ${_pyqtside_SCRIPTS} DESTINATION ${PYQTSIDE_TEST_INSTALL})
index 6e90c29e8df0979aec367bafb1469210640412ad..173cb052cee3206d2ddef7817e4fdf62fd411735 100644 (file)
@@ -1,7 +1,7 @@
 from . import _use_pyqt
 if _use_pyqt:
-  from PyQt4.QtCore import *
-  Slot = pyqtSlot  
-  Signal = pyqtSignal 
+  from PyQt5.QtCore import *
+  Slot = pyqtSlot
+  Signal = pyqtSignal
 else:
   from PySide.QtCore import *
index 15c7ee1f10721ff25f6dd50930d2495cb77e4c02..64e3d09386dd2535068bfb4843af6fb366d205b9 100644 (file)
@@ -1,37 +1,37 @@
 from . import _use_pyqt
 if _use_pyqt:
-  from PyQt4.QtGui import *
-  
-  # Make QVariant invisible in PyQt4 since they don't exist in
+  from PyQt5.QtGui import *
+
+  # Make QVariant invisible in PyQt5 since they don't exist in
   # PySide ...
-  __original_itemData = QComboBox.itemData
-  def new_itemData(*args, **kargs):
-    from PyQt4.QtCore import QVariant
-    variant = __original_itemData(*args, **kargs)
-    funcS = lambda : (str(variant.toString()), True)
-    dico = {QVariant.Int: variant.toInt, QVariant.String: funcS,
-     QVariant.Bool: variant.toBool, QVariant.Double: variant.toDouble}
-    conv = dico.get(variant.type(), None)
-    if conv is None:
-      raise Exception("Unsupported variant type in pyqtside: '%s'!" % variant.typeName())
-    return conv()[0]
-  
-  QComboBox.itemData = new_itemData 
+#  __original_itemData = QComboBox.itemData
+#  def new_itemData(*args, **kargs):
+#    from PyQt5.QtCore import QVariant
+#    variant = __original_itemData(*args, **kargs)
+#    funcS = lambda : (str(variant.toString()), True)
+#    dico = {QVariant.Int: variant.toInt, QVariant.String: funcS,
+#     QVariant.Bool: variant.toBool, QVariant.Double: variant.toDouble}
+#    conv = dico.get(variant.type(), None)
+#    if conv is None:
+#      raise Exception("Unsupported variant type in pyqtside: '%s'!" % variant.typeName())
+#    return conv()[0]
+#
+#  QComboBox.itemData = new_itemData 
 else:
   from PySide.QtGui import *
-  
+
   __original_ofn = QFileDialog.getOpenFileName
   __original_sfn = QFileDialog.getSaveFileName
-  
-  # In PySide, getOpenFileName and co returns 2 values, and only one in PyQt4 ...
+
+  # In PySide, getOpenFileName and co returns 2 values, and only one in PyQt ...
   def newOfn(cls,*args, **kargs):
     tup = __original_ofn(*args, **kargs)
     return tup[0]
-    
+
   def newSfn(cls,*args, **kargs):
     tup = __original_sfn(*args, **kargs)
     return tup[0]
-    
+
   QFileDialog.getOpenFileName = classmethod(newOfn)
   QFileDialog.getSaveFileName = classmethod(newSfn)
 
diff --git a/tools/CurvePlot/src/python/pyqtside/QtWidgets.py b/tools/CurvePlot/src/python/pyqtside/QtWidgets.py
new file mode 100644 (file)
index 0000000..dd00a92
--- /dev/null
@@ -0,0 +1,5 @@
+from . import _use_pyqt
+if _use_pyqt:
+  from PyQt5.QtWidgets import *
+else:
+  from PySide.QtWidgets import *
index 1cba014b11df652d919d305268ad076f34e42b49..39dc7c587bbfa6ae742a0c07647d2ec95345d36c 100644 (file)
@@ -1,29 +1,32 @@
 """
-Group under one hat PySide and PyQt4. PyQt4 is tried first.
+Group under one hat PySide and PyQt5. PyQt5 is tried first.
 """
 
 try:
   import os
   if os.getenv("CURVEPLOT_FORCE_PYSIDE") is not None:
     raise Exception
-  import PyQt4
+  import PyQt5
   _use_pyqt = True
-  print("Using PyQt4 run-time ...")
+  print("Using PyQt5 run-time ...")
 except:
   try:
     import PySide
     _use_pyqt = False
     print("Using PySide run-time ...")
   except:
-    raise Exception("Neither PyQt4 nor PySide could be imported!")
+    raise Exception("Neither PyQt5 nor PySide could be imported!")
 
 # Matplotlib has to be handled very early, otherwise it will switch to whatever it
 # finds first on the machine
 try: 
   import matplotlib
-  if _use_pyqt:  back = 'PyQt4'
+  if _use_pyqt:  back = 'PyQt5'
   else:          back = 'PySide'
-  matplotlib.rcParams['backend.qt4'] = back
+  # As advised by MatPlotlib:
+  #   "The backend.qt5 rcParam was deprecated in version 2.2.  In order to force the use of a specific Qt binding, either import that binding first, or set the QT_API environment variable.
+  #   mplDeprecation)"
+  from matplotlib.backends import backend_qt5agg
   print("Matplotlib found - Set matplotlib backend to '%s'!" % back) 
 except:
   # No matplotlib, silently discard err message.
index a3ab6046d95d1c1e3c3fac9527d6b2c0fac93dbc..38a82e3b680c81911141883a3be47c5915ac650e 100644 (file)
@@ -14,7 +14,7 @@ class UiLoader(QUiLoader):
     create a new instance of the top-level widget, but creates the user
     interface in an existing instance of the top-level class.
 
-    This mimics the behaviour of :func:`PyQt4.uic.loadUi`.
+    This mimics the behaviour of :func:`PyQt5.uic.loadUi`.
     """
     def __init__(self, baseinstance, customWidgets=None):
         """
index 6cc1465107f53c5831b8dbecac4f4f4cb8f7e9b2..278741ff05b233bec5c152d6f69adc83006bcaea 100644 (file)
@@ -1,7 +1,7 @@
 from . import _use_pyqt
 if _use_pyqt:
-  from PyQt4.uic import loadUi as loadUiGen
-else: 
+  from PyQt5.uic import loadUi as loadUiGen
+else:
   from .pyside_dynamic import loadUi as loadUiGen
 
 
index 24f9eca1489a08716a415b7e5a91e67cfdd272dd..17d7c91672163f111afd02e0d970172eebd79fec 100644 (file)
@@ -26,20 +26,23 @@ SET(_all_SCRIPTS
     TestDesktop.py
 )
 
+SET(_test_SCRIPTS
+    ${CMAKE_CURRENT_BINARY_DIR}/mockup/SalomePyQt_MockUp.py
+    PlotTestBase.py
+    TestDesktop.py
+)
+
 SALOME_INSTALL_SCRIPTS("${_all_SCRIPTS}" ${SALOME_INSTALL_SCRIPT_PYTHON}/tests)
 SALOME_INSTALL_SCRIPTS(${CMAKE_CURRENT_BINARY_DIR}/mockup/SalomePyQt_MockUp.py ${SALOME_INSTALL_SCRIPT_PYTHON}/tests)
 
 INSTALL(DIRECTORY baselines DESTINATION ${SALOME_INSTALL_SCRIPT_PYTHON}/tests)
 
-SALOME_ACCUMULATE_ENVIRONMENT(PYTHONPATH ${CMAKE_CURRENT_SOURCE_DIR}/../model)
-SALOME_ACCUMULATE_ENVIRONMENT(PYTHONPATH ${CMAKE_CURRENT_SOURCE_DIR}/../ui)
-SALOME_ACCUMULATE_ENVIRONMENT(PYTHONPATH ${CMAKE_CURRENT_SOURCE_DIR}/../views)
-SALOME_ACCUMULATE_ENVIRONMENT(PYTHONPATH ${CMAKE_CURRENT_SOURCE_DIR}/../controller)
-SALOME_ACCUMULATE_ENVIRONMENT(PYTHONPATH ${CMAKE_CURRENT_SOURCE_DIR}/..)
-SALOME_ACCUMULATE_ENVIRONMENT(PYTHONPATH ${PROJECT_BINARY_DIR}/src/python/ui)  # for the generated PY files (from UI files)
-SALOME_ACCUMULATE_ENVIRONMENT(PYTHONPATH ${PROJECT_BINARY_DIR}/src/python/controller)  # for utils.py
+SALOME_ACCUMULATE_ENVIRONMENT(PYTHONPATH ${CMAKE_BINARY_DIR}/local)  # point to local curveplot package in BUILD dir
 SALOME_GENERATE_TESTS_ENVIRONMENT(tests_env)
 
 ADD_TEST(CurvePlotUnitTests ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/plot_test.py)
 SET_TESTS_PROPERTIES(CurvePlotUnitTests PROPERTIES ENVIRONMENT "${tests_env}")
 
+# For test purposes
+FILE(COPY ${_test_SCRIPTS} DESTINATION ${CRVPLOT_TEST_INSTALL})
+FILE(COPY baselines DESTINATION ${CRVPLOT_TEST_INSTALL})
index 4097dedf0dd4f5e001e0d264cf1b95aa0b78ffcd..f43335277e97a5671df81540de7109f69a7057fa 100755 (executable)
@@ -22,8 +22,8 @@
 #
 # Author : A. Bruneton
 #
-from pyqtside.QtGui import QApplication 
-from pyqtside.QtCore import SIGNAL, SLOT, QTimer, QTranslator
+from pyqtside.QtWidgets import QApplication
+from pyqtside.QtCore import QTimer, QTranslator
 
 from TestDesktop import TestDesktop
 import SalomePyQt_MockUp
@@ -43,31 +43,23 @@ def activeViewChanged( viewID ):
 
 def main(args) :
     global desktop
-      
+
     app = QApplication(args)
-    ts_files = ["/export/home/adrien/Projets/salome/modules/V7_main/CURVEPLOT_INSTALL/share/salome/resources/curveplot/CURVEPLOT_msg_fr.qm",
-                "/export/home/adrien/Projets/salome/modules/V7_main/CURVEPLOT_INSTALL/share/salome/resources/curveplot/CURVEPLOT_msg_en.qm"
-                ]
-    trans = QTranslator()
-    for f in ts_files:
-      if not trans.load(f):
-        print("could not load translation %s!" % f)
-    app.installTranslator(trans)
     dw = app.desktop()
     x, y = dw.width()*0.25, dw.height()*0.7
-    
+
     desktop = TestDesktop(None)
     sgPyQt = SalomePyQt_MockUp.SalomePyQt(desktop)
     sgPyQt.currentTabChanged.connect(activeViewChanged)
-    desktop._sgPyQt = sgPyQt 
+    desktop._sgPyQt = sgPyQt
     desktop.initialize()
     desktop.resize(x,y)
     desktop.show()
     activate()
     #
-    QTimer.singleShot(200, desktop, SLOT("curveSameFig()"))
+    QTimer.singleShot(200, desktop.curveSameFig)
     #
-    app.connect(app,SIGNAL("lastWindowClosed()"),app,SLOT("quit()"))
+    app.lastWindowClosed.connect(app.quit)
     app.exec_()
 
 if __name__ == "__main__" :
index e9cfc9aaa4fab91a0433ab67af2b8cb6407cbe27..5c7e5715350096d036fda03f2312a95771aa8691 100644 (file)
 # Author : A. Bruneton
 #
 import unittest, sys, os, filecmp, shutil, tempfile
-from pyqtside.QtGui import QApplication, QPixmap, QPainter
-from PlotController import PlotController
-from XYView import XYView
+from pyqtside.QtWidgets import QApplication
+from pyqtside.QtGui import QPixmap, QPainter
+from pyqtside.QtCore import QTimer
+
+from curveplot.PlotController import PlotController
+from curveplot.XYView import XYView
+from PyQt5.Qt import QMainWindow
 
 def runOnly(func):
   func.__runOnly__ = True
@@ -51,7 +55,7 @@ def processDecorator(mod_name):
           # Note the "not":
           if p.startswith("test") and not hasattr(obj.__dict__[p], "__runOnly__"):
             delattr(obj, p)
+
 class PlotTestBase(unittest.TestCase):
   """ Unit test suite for the curve plotter. This class deals with the set up and the screenshot generation/
   comparison. The tests themselves are stored in the derived class PlotTest below.
@@ -61,31 +65,30 @@ class PlotTestBase(unittest.TestCase):
   The baselines directory is set relative to the path of this script.
   """
   REBUILD_BASELINES = False
-  
+
   __BASE_LINE_DIR = "baselines"
   __FORMAT = "png"
-  
+
   def __init__(self, methodName):
     unittest.TestCase.__init__(self, methodName)
-     
+
     if self.REBUILD_BASELINES:
       self.tmpBaselineDir = os.path.join(tempfile.gettempdir(), "curveplot_baselines")
       if not os.path.isdir(self.tmpBaselineDir):
         os.mkdir(self.tmpBaselineDir)
       print("### Rebuilding base lines. Reference files will be saved to '%s'" % self.tmpBaselineDir)
-       
+
     PlotController.WITH_CURVE_BROWSER = True
     XYView._DEFAULT_LEGEND_STATE = True   # always show legend by default
     self._this_dir = os.path.dirname(os.path.realpath(__file__))
-    
-#     import matplotlib as mpl
-#     mpl.use('Agg')
-  
+
   def setUp(self):
-    from SalomePyQt_MockUp import SalomePyQt
-    from TableModel import TableModel
-    from CurveModel import CurveModel
-    from XYPlotSetModel import XYPlotSetModel
+    import sys
+    from curveplot.SalomePyQt_MockUp import SalomePyQt
+    from curveplot.TableModel import TableModel
+    from curveplot.CurveModel import CurveModel
+    from curveplot.XYPlotSetModel import XYPlotSetModel
+    from curveplot.TestDesktop import TestDesktop
 
     self.qpixmap = None
     self.keepDir = False
@@ -93,21 +96,30 @@ class PlotTestBase(unittest.TestCase):
       self.tmpDir = tempfile.mkdtemp(prefix="curveplot_tests")
     else:
       self.tmpDir = None
+
     # Minimal UI setup:
-    self.sgPyQt = SalomePyQt()
-    # Reinstanciate from scratch the PlotController:
+    self.app = QApplication(sys.argv)
+    desktop = TestDesktop(None)
+    self.sgPyQt = SalomePyQt(desktop)
+    desktop._sgPyQt = self.sgPyQt
+    desktop.initialize()
     self.plotController = PlotController.GetInstance(self.sgPyQt)
-    self.plotController.setFixedSizeWidget()
+    desktop.resize(800, 600)
+    desktop.show()
+    self._execQtWasCalled = False # Used to automatically finish Qt execution loop on tests not doing a screenshot
+
     # Reset some class var to make sure IDs appearing in screenshots do not depend on test seq order:
     CurveModel.START_ID = -1
     TableModel.START_ID = -1
     XYPlotSetModel.START_ID = -1
-        
+
   def tearDown(self):
     if not self.REBUILD_BASELINES:
       # Clean up temp dir where the file comparison has been made:
       if not self.keepDir:
         shutil.rmtree(self.tmpDir, False)
+    if not self._execQtWasCalled:
+      self._execQt(withShot=False)
     PlotController.Destroy()
 
   def getTestName(self):
@@ -118,7 +130,29 @@ class PlotTestBase(unittest.TestCase):
     self.qpixmap.save(fileName, self.__FORMAT)
     return fileName
 
-  def areScreenshotEqual(self, widget, suffix=""):
+  def _execQt(self, withShot=False):
+    if withShot:
+      QTimer.singleShot(50, self._shotEvent)  # take picture
+    QTimer.singleShot(200, self.app.quit)    # quit
+    self.app.exec_()  # will hang till quit is fired
+
+    # Important make sure previous app is properly killed before launching next test!
+    # Qt doesn't like multiple running instance
+    import gc
+    gc.collect()
+
+  def areScreenshotEqual(self, widget):
+    """ Finish the launching of the Qt application so that the widgets and the curve have a chance to display
+     and trigger snapshot comparison """
+    self.saveW = widget
+    self._execQtWasCalled = True
+    self._execQt(withShot=True)
+    return self.retValue
+
+  def _shotEvent(self):
+    self.retValue = self._snapAndCompare(self.saveW)
+
+  def _snapAndCompare(self, widget, suffix=""):
     """ Test equality between a reference file saved in the baseline directory, and whose name is built as
           "<test_name><suffix>.png"
         and the file generated on the fly by taking a snapshot of the widget provided in argument.
@@ -126,13 +160,16 @@ class PlotTestBase(unittest.TestCase):
     """
     import glob
     # Smiiiile :-)
-    self.qpixmap = QPixmap.grabWidget(widget)
-    
+    self.qpixmap = QPixmap(widget.size())
+    widget.repaint()
+    widget.render(self.qpixmap)
+    #self.qpixmap = widget.grab()
+
     # Nothing to compare if rebuilding base lines, just saving file:
     if self.REBUILD_BASELINES:
       self.saveCurrentPix(self.tmpBaselineDir, suffix)
       return True
-    
+
     gen_path = self.saveCurrentPix(self.tmpDir, suffix)
     base_ref = os.path.join(self._this_dir, self.__BASE_LINE_DIR, self.getTestName() + suffix)
     ret = False
@@ -147,13 +184,13 @@ class PlotTestBase(unittest.TestCase):
       # Keep file if assert is false
       self.keepDir = True
       print("[%s] -- Failed screenshot equality, or unable to open baseline file - directory is kept alive: %s" % (self.getTestName(), self.tmpDir))
-    return ret 
-  
+    return ret
+
   def showTabWidget(self):
     tabW = self.plotController._sgPyQt._tabWidget
     # No simpler way found so far:
     tabW.show()
     return tabW
-    
+
   def getBrowserWidget(self):
     return self.plotController._curveBrowserView._treeWidget
index bdb40251fb72bf99c069d41ba3b0afeae4cb472d..cbc22eaf7921f90ace4cd3a14deaee8680e7609b 100644 (file)
@@ -1,4 +1,12 @@
-Unit tests are in plot_test.py
+Unit tests are in plot_test.py.
+
+They should be run: 
+    - without any install of CurvePlot, to be sure there is no conflict
+    - with the ctest command 
+
+If anything is changed in the code, be sure to explicitely call
+    cmake .
+in the build directory to update the local replica of the 'curveplot' package.
 
 PlotCurve_Standalone is a standalone Python executable that shows the
 various functionalities of the package.
index ad5d2d6f8b44063d1e368707fe2dc37e374f4d64..44814d1d6b94499682f09efa03fdc0ae3d34fa57 100644 (file)
 # Author : A. Bruneton
 #
 
-from pyqtside.QtGui import QApplication, QTabWidget 
-from pyqtside.QtGui import QAction, QMenu, QIcon, QPixmap, QDesktopWidget, QFileDialog
-from pyqtside.QtCore import SIGNAL, SLOT, QObject, Slot, Signal
+from pyqtside.QtWidgets import QApplication, QTabWidget 
+from pyqtside.QtWidgets import QAction, QMenu, QDesktopWidget, QFileDialog
+from pyqtside.QtGui import QIcon, QPixmap
+from pyqtside.QtCore import QObject, pyqtSlot, pyqtSignal
 
 RESOURCE_DIR = "@SGPYQT_RES_DIR@"
 
@@ -33,7 +34,7 @@ class SalomePyQt(QObject):
   This class can be used to mimick the true SALOME object without having to launch 
   SALOME
   """  
-  currentTabChanged = Signal(int)
+  currentTabChanged = pyqtSignal(int)
   
   START_VIEW_ID = 0
   
@@ -47,7 +48,7 @@ class SalomePyQt(QObject):
     if self._mainWindow:
       self._menuBar = self._mainWindow.menuBar()
       self._mainWindow.setCentralWidget(self._tabWidget)
-    self.connect(self._tabWidget, SIGNAL("currentChanged(int)"), self, SLOT("onTabChanged(int)"))
+    self._tabWidget.currentChanged.connect(self.onTabChanged)
     self._blockSignal = False
   
   def getDesktop(self):
@@ -58,12 +59,12 @@ class SalomePyQt(QObject):
     return QFileDialog.getSaveFileName(parent=parent_widget,
                                        caption=caption, directory=initial, filter=fil);
   
-  @Slot(int)
+  @pyqtSlot(int)
   def onTabChanged(self, index):
     if self._blockSignal:
       return
     invDict = dict([(v, k) for k,v in self._viewIDs.items()])
-    if invDict.has_key(index):
+    if index in invDict:
       self._blockSignal = True
       self.currentTabChanged.emit(invDict[index])
       self._blockSignal = False
index 142fcf64f54d1befd02367d44f2793651c8ef48c..b09ca0ace0ec36b18ea6a448cef683ad85b42747 100644 (file)
@@ -23,8 +23,8 @@
 # Author : A. Bruneton
 #
 
-from pyqtside.QtCore import SIGNAL, SLOT, Slot, Qt, QTimer
-from pyqtside.QtGui import QMainWindow,QMenu
+from pyqtside.QtCore import Qt, QTimer, pyqtSlot
+from pyqtside.QtWidgets import QMainWindow,QMenu
 import numpy as np
 
 import curveplot
@@ -70,15 +70,15 @@ class TestDesktop(QMainWindow):
         self.createMenus()
         self.createView()
         
-        self.connect(self.curveSameFigAction,SIGNAL("activated()"),self.curveSameFig)
-        self.connect(self.curveNewFigAction,SIGNAL("activated()"),self.curveNewFig)
-        self.connect(self.itemDelAction,SIGNAL("activated()"),self.itemDel)
-        self.connect(self.cpsAction,SIGNAL("activated()"),self.clearPlotSet)
-        self.connect(self.plotTableAction,SIGNAL("activated()"),self.plotTable)
-        self.connect(self.addPSAction,SIGNAL("activated()"),self.addPS)
-        self.connect(self.addTabAction,SIGNAL("activated()"),self.addTab)
-        self.connect(self.memAction,SIGNAL("activated()"),self.memPrint)
-        self.connect(self.perfTestAction,SIGNAL("activated()"),self.perfTest)
+        self.curveSameFigAction.triggered.connect(self.curveSameFig)
+        self.curveNewFigAction.triggered.connect(self.curveNewFig)
+        self.itemDelAction.triggered.connect(self.itemDel)
+        self.cpsAction.triggered.connect(self.clearPlotSet)
+        self.plotTableAction.triggered.connect(self.plotTable)
+        self.addPSAction.triggered.connect(self.addPS)
+        self.addTabAction.triggered.connect(self.addTab)
+        self.memAction.triggered.connect(self.memPrint)
+        self.perfTestAction.triggered.connect(self.perfTest)
 
     def generateID(self):
         self._currID += 1
@@ -152,7 +152,7 @@ class TestDesktop(QMainWindow):
 #       y = x
       return x, y
        
-    @Slot()  
+    @pyqtSlot()
     def curveSameFig(self):
       x, y = self.__generateRandomData()
       _, ps_id = curveplot.AddCurve(x, y, x_label="the x axis", y_label="the y axis", append=True)
@@ -164,13 +164,13 @@ class TestDesktop(QMainWindow):
       x, y = self.__generateRandomData()
       curveplot.AddCurve(x, y, x_label="the x axis", y_label="the y axis", append=False)
     
-    @Slot()
+    @pyqtSlot()
     def itemDel(self):
       curveplot.DeleteCurrentItem()
       if self.cnt >= 0:
         QTimer.singleShot(self.timeLap, self, SLOT("memPrint()"))
 
-    @Slot()
+    @pyqtSlot()
     def perfTest(self):
       lx, ly = [], []
       nC = 200
@@ -195,7 +195,7 @@ class TestDesktop(QMainWindow):
       
     def addTab(self):
       pass
-#      from PyQt4.QtGui import QPushButton
+#      from PyQt5.QtWidgets import QPushButton
 #      self.qp = QPushButton("Hi!")
 #      self._sgPyQt.createView("Dummy", self.qp)  
       
@@ -213,7 +213,7 @@ class TestDesktop(QMainWindow):
       cont.plotCurveFromTable(t, y_col_index=1, append=False)
       cont.plotCurveFromTable(t, y_col_index=2, append=True)
     
-    @Slot()
+    @pyqtSlot()
     def memPrint(self):
       i, t = curveplot.GetAllPlotSets()
       print(list(zip(i, t)))
@@ -224,4 +224,4 @@ class TestDesktop(QMainWindow):
       print("** Used memory: %.2f Mb" % m)
       if self.cnt >= 0 and self.cnt < self.MAX_CNT:
         self.cnt += 1
-        QTimer.singleShot(self.timeLap, self, SLOT("curveSameFig()"))
+        QTimer.singleShot(self.timeLap, self.curveSameFig)
index 3058925ffd7d7a8b49b6b16bf7b3126f2fdedb1e..d791e16ca4e6bcca496465b480afe9702545afa2 100644 (file)
 #
 # Author : A. Bruneton
 #
+from curveplot import *
+from curveplot.PlotTestBase import PlotTestBase, processDecorator
+from curveplot.PlotSettings import PlotSettings
 
-from PlotTestBase import PlotTestBase, runOnly, processDecorator
-
-from PlotController import PlotController
-from PlotSettings import PlotSettings
-
-from pyqtside.QtGui import QApplication
+from pyqtside.QtWidgets import QApplication
 import sys
-qapp = QApplication(sys.argv)  
-  
+qapp = QApplication(sys.argv)
+
 class PlotTest(PlotTestBase):
   """ Unit test suite for the curve plotter. The tests themselves are stored in this class,
   the screenshot comparison logic is in PlotTestBase.
@@ -43,10 +41,10 @@ class PlotTest(PlotTestBase):
   The decorator @runOnly can be used to run/rebuild a single test.
   """
   REBUILD_BASELINES = False
-  
+
   def __init__(self, methodName):
     PlotTestBase.__init__(self, methodName)
-  
+
   ###
   ### Data generation
   ###
@@ -55,24 +53,24 @@ class PlotTest(PlotTestBase):
     x = np.arange(100)
     y = np.sin(x*alpha/np.pi)
     return x, y
-  
+
   def generateExp(self, alpha=1.0):
     import numpy as np
     x = np.arange(20) + 1.0
     y = np.exp(x*alpha)
     return x, y
-   
+
   ###
   ### The tests themselves
   ###
-    
+
   #
   # Non GUI tests (some of them still need to show the widget to work properly but no
   # screenshot comparison is made).
   #
   def testTableModel(self):
     import numpy as np
-    from TableModel import TableModel
+    from curveplot.TableModel import TableModel
     t = TableModel(None)
     t.setTitle("coucou")
     t.addColumn([1.0,2.0,3.0,4.0])
@@ -85,25 +83,25 @@ class PlotTest(PlotTestBase):
     t.setColumnTitle(1, "a title")
     self.assertEqual("a title", t.getColumnTitle(1))
     self.assertEqual("", t.getColumnTitle(0))
-       
+
   def testGetAllPlotSets(self):
     self.showTabWidget()
     ids, titles = PlotController.GetAllPlotSets()
     self.assertEqual([], ids)
     self.assertEqual([], titles)
-         
+
     id1 = PlotController.AddPlotSet("toto")
     id2 = PlotController.AddPlotSet("tutu")
     id3 = PlotController.AddPlotSet("titi")
     ids, titles = PlotController.GetAllPlotSets()
     self.assertEqual([id1,id2,id3], ids)
     self.assertEqual(["toto","tutu","titi"], titles)
-     
+
   def testGetCurrentXX(self):
     self.showTabWidget()
     self.assertEqual(-1, PlotController.GetCurrentCurveID())
     self.assertEqual(-1, PlotController.GetCurrentPlotSetID())
-      
+
     x, y = self.generateSine()
     _, psID1 = PlotController.AddCurve(x, y, append=False)
     self.assertEqual(psID1, PlotController.GetCurrentPlotSetID())
@@ -116,7 +114,7 @@ class PlotTest(PlotTestBase):
     PlotController.DeletePlotSet(psID2)
     self.assertEqual(-1, PlotController.GetCurrentCurveID())
     self.assertEqual(-1, PlotController.GetCurrentPlotSetID())
-         
+
   def testGetPlotSetID(self):
     self.showTabWidget()
     x, y = self.generateSine()
@@ -125,7 +123,7 @@ class PlotTest(PlotTestBase):
     self.assertEqual(-1, PlotController.GetPlotSetID(145))  # invalid ID
     PlotController.DeletePlotSet(psID)
     self.assertEqual(-1, PlotController.GetPlotSetID(crvID))  # invalid ID
-        
+
   def testGetPlotSetIDByName(self):
     self.showTabWidget()
     self.assertEqual(-1,PlotController.GetPlotSetIDByName("invalid"))
@@ -133,7 +131,7 @@ class PlotTest(PlotTestBase):
     self.assertEqual(psID,PlotController.GetPlotSetIDByName("ps"))
     PlotController.DeletePlotSet(psID)
     self.assertEqual(-1,PlotController.GetPlotSetIDByName("ps"))
-        
+
   def testIsValidPlotSetID(self):
     self.showTabWidget()
     self.assertEqual(False,PlotController.IsValidPlotSetID(0))
@@ -141,16 +139,16 @@ class PlotTest(PlotTestBase):
     self.assertEqual(True,PlotController.IsValidPlotSetID(psID))
     PlotController.DeletePlotSet(psID)
     self.assertEqual(False,PlotController.IsValidPlotSetID(psID))
-      
+
   #
   # GUI tests
-  #    
+  #
   def testAddCurve(self):
     x, y = self.generateSine()
     tw = self.showTabWidget()
     PlotController.AddCurve(x, y, curve_label="My curve", x_label="Lèés X (unicode!)", y_label="Et des ŷ", append=False)
     self.assertTrue(self.areScreenshotEqual(tw))
-      
+
   def testAddCurveAppend(self):
     x, y = self.generateSine()
     tw = self.showTabWidget()
@@ -162,12 +160,12 @@ class PlotTest(PlotTestBase):
     tw = self.showTabWidget()
     PlotController.AddPlotSet("My plotset")
     self.assertTrue(self.areScreenshotEqual(tw))
-          
+
   def testClearPlotSet(self):
     x, y = self.generateSine()
     tw = self.showTabWidget()
     PlotController.AddCurve(x, y, curve_label="My curve", x_label="The X-s", y_label="The Y-s", append=False)
-    _, psID = PlotController.AddCurve(x, y, curve_label="My curve 2", append=True)    
+    _, psID = PlotController.AddCurve(x, y, curve_label="My curve 2", append=True)
     clearedID = PlotController.ClearPlotSet()
     self.assertEqual(clearedID, psID)
     self.assertTrue(self.areScreenshotEqual(tw))
@@ -179,7 +177,7 @@ class PlotTest(PlotTestBase):
     clearedID = PlotController.ClearPlotSet(psID)
     self.assertEqual(psID, clearedID)
     self.assertTrue(self.areScreenshotEqual(tw))
-          
+
   def testCopyCurve(self):
     x, y = self.generateSine()
     tw = self.showTabWidget()
@@ -189,7 +187,7 @@ class PlotTest(PlotTestBase):
     PlotController.SetCurrentPlotSet(psID)
     self.assertNotEqual(crvID, newID)
     self.assertTrue(self.areScreenshotEqual(tw))
-          
+
   def testDeleteCurrentItem_curve(self):
     x, y = self.generateSine()
     tw = self.showTabWidget()
@@ -200,7 +198,7 @@ class PlotTest(PlotTestBase):
     self.assertFalse(b)
     self.assertEqual(crvID, anID)
     self.assertTrue(self.areScreenshotEqual(tw))
-          
+
   def testDeleteCurrentItem_plotSet(self):
     tw = self.showTabWidget()
     PlotController.AddPlotSet("tutu")
@@ -209,13 +207,13 @@ class PlotTest(PlotTestBase):
     self.assertTrue(b)
     self.assertEqual(psID, anID)
     self.assertTrue(self.areScreenshotEqual(tw))
-            
+
   def testDeleteCurrentItem_void(self):
     self.showTabWidget()
-    b, anID = PlotController.DeleteCurrentItem()  # nothing selected 
+    b, anID = PlotController.DeleteCurrentItem()  # nothing selected
     self.assertTrue(b)
     self.assertEqual(-1, anID)
-          
+
   def testDeleteCurve1(self):
     tw = self.showTabWidget()
     x, y = self.generateSine()
@@ -224,7 +222,7 @@ class PlotTest(PlotTestBase):
     cID = PlotController.DeleteCurve(crvID)
     self.assertEqual(crvID, cID)
     self.assertTrue(self.areScreenshotEqual(tw))
-        
+
   def testDeleteCurve2(self):
     tw = self.showTabWidget()
     x, y = self.generateSine()
@@ -234,16 +232,16 @@ class PlotTest(PlotTestBase):
     cID = PlotController.DeleteCurve()   # current curve
     self.assertEqual(crvID, cID)
     self.assertTrue(self.areScreenshotEqual(tw))
-     
+
   def testDeleteCurve3(self):
     """ resulting in an empty plot set, legend should be hidden """
     tw = self.showTabWidget()
     x, y = self.generateSine()
     crvID, _ = PlotController.AddCurve(x, y, append=False)
-    cID = PlotController.DeleteCurve(crvID) 
+    cID = PlotController.DeleteCurve(crvID)
     self.assertEqual(crvID, cID)
     self.assertTrue(self.areScreenshotEqual(tw))
-        
+
   def testDeletePlotSet1(self):
     tw = self.showTabWidget()
     psID = PlotController.AddPlotSet("tutu")
@@ -251,7 +249,7 @@ class PlotTest(PlotTestBase):
     psID2 = PlotController.DeletePlotSet(psID)
     self.assertEqual(psID2, psID)
     self.assertTrue(self.areScreenshotEqual(tw))
-        
+
   def testDeletePlotSet2(self):
     tw = self.showTabWidget()
     psID1 = PlotController.DeletePlotSet()
@@ -262,7 +260,7 @@ class PlotTest(PlotTestBase):
     psID3 = PlotController.DeletePlotSet()  # current plot set
     self.assertEqual(psID3, psID2)
     self.assertTrue(self.areScreenshotEqual(tw))
-        
+
   def testSetCurrentCurve(self):
     tw = self.showTabWidget()
     self.assertRaises(ValueError, PlotController.SetCurrentCurve, 23)
@@ -272,7 +270,7 @@ class PlotTest(PlotTestBase):
     psID2 = PlotController.SetCurrentCurve(crvID)
     self.assertEqual(psID, psID2)
     self.assertTrue(self.areScreenshotEqual(tw))
-        
+
   def testSetCurrentCurve2(self):
     tw = self.showTabWidget()
     x, y = self.generateSine()
@@ -283,7 +281,7 @@ class PlotTest(PlotTestBase):
     # on first plot set curve should not be selected anymore
     PlotController.SetCurrentPlotSet(psID)
     self.assertTrue(self.areScreenshotEqual(tw))
-  
+
   def testSetCurrentCurve3(self):
     tw = self.showTabWidget()
     x, y = self.generateSine()
@@ -292,7 +290,7 @@ class PlotTest(PlotTestBase):
     PlotController.SetCurrentCurve(crvID)
     PlotController.SetCurrentCurve(-1)
     self.assertTrue(self.areScreenshotEqual(tw))
-        
+
   def testSetCurrentPlotSet(self):
     tw = self.showTabWidget()
     psID = PlotController.AddPlotSet("tutu")
@@ -300,7 +298,7 @@ class PlotTest(PlotTestBase):
     PlotController.SetCurrentPlotSet(psID)
     self.assertTrue(self.areScreenshotEqual(tw))
     self.assertRaises(ValueError, PlotController.SetCurrentPlotSet, 124) # invalid ps_id
-     
+
   def testSetLabelX(self):
     tw = self.showTabWidget()
     ps_id = PlotController.AddPlotSet("My plotset")
@@ -321,14 +319,14 @@ class PlotTest(PlotTestBase):
     PlotController.SetPlotSetTitle("un titre àé", ps_id)
     PlotController.SetCurrentPlotSet(ps_id)
     self.assertTrue(self.areScreenshotEqual(tw))
-        
+
 #   def testToggleCurveBrowser(self):
 #     # hard to test ...
 #     raise NotImplementedError
-          
+
   def testPlotCurveFromTable(self):
     tw = self.showTabWidget()
-    from TableModel import TableModel
+    from curveplot.TableModel import TableModel
     t = TableModel(None)
     t.setTitle("coucou")
     t.addColumn([1.0,2.0,3.0,4.0])
@@ -352,21 +350,21 @@ class PlotTest(PlotTestBase):
     def fun():
       dlg_test.setRGB(0,0,0)
       dlg_test.showLegendCheckBox.setChecked(True)
-      return True  
+      return True
     dlg_test.exec_ = fun
     t = list(PlotController.GetInstance()._curveTabsView._XYViews.items())
-    t[0][1].onSettings(dlg_test=dlg_test)  
+    t[0][1].onSettings(dlg_test=dlg_test)
     self.assertTrue(self.areScreenshotEqual(tw))
+
   def testExtendCurve(self):
     tw = self.showTabWidget()
     x, y = self.generateSine()
     crvID, _ = PlotController.AddCurve(x, y, append=False)
     PlotController.SetCurrentCurve(crvID)
     PlotController.ExtendCurve(crvID, x+100.0, y*2.0)
-    # Curve must remain blue, bold and with first marker:      
+    # Curve must remain blue, bold and with first marker:
     self.assertTrue(self.areScreenshotEqual(tw))
-     
+
   def testResetCurve(self):
     tw = self.showTabWidget()
     x, y = self.generateSine()
@@ -374,7 +372,7 @@ class PlotTest(PlotTestBase):
     PlotController.SetCurrentCurve(crvID)
     PlotController.ResetCurve(crvID)
     PlotController.ExtendCurve(crvID, x+100.0, y*x)
-    # Curve must remain blue, bold and with first marker:      
+    # Curve must remain blue, bold and with first marker:
     self.assertTrue(self.areScreenshotEqual(tw))
 
   def testSettingsCurveMarker(self):
@@ -387,19 +385,19 @@ class PlotTest(PlotTestBase):
     def fun():
       dlg_test.markerCurve.setCurrentIndex(2)
       dlg_test.showLegendCheckBox.setChecked(True)
-      return True  
+      return True
     dlg_test.exec_ = fun
     t = list(PlotController.GetInstance()._curveTabsView._XYViews.items())
-    t[0][1].onSettings(dlg_test=dlg_test)  
+    t[0][1].onSettings(dlg_test=dlg_test)
     self.assertTrue(self.areScreenshotEqual(tw))
-    
+
   def testSetCurveMarker(self):
     tw = self.showTabWidget()
     x, y = self.generateSine()
     crvID, _ = PlotController.AddCurve(x, y, append=False)
     PlotController.SetCurveMarker(crvID, "v")
     self.assertTrue(self.areScreenshotEqual(tw))
-  
+
   def testSetCurveLabel(self):
     tw = self.showTabWidget()
     x, y = self.generateSine()
@@ -408,7 +406,7 @@ class PlotTest(PlotTestBase):
     PlotController.SetCurrentCurve(crvID)
     PlotController.SetCurveLabel(crvID, "tata")
     self.assertTrue(self.areScreenshotEqual(tw))
-    
+
   def testToggleXLog(self):
     tw = self.showTabWidget()
     x, y = self.generateExp()
@@ -424,7 +422,7 @@ class PlotTest(PlotTestBase):
     PlotController.SetYLog(psID, True)
     PlotController.SetYSciNotation(psID, True)
     self.assertTrue(self.areScreenshotEqual(tw))
-  
+
   def testSetXSciNotation(self):
     tw = self.showTabWidget()
     x, y = self.generateSine()
@@ -438,7 +436,7 @@ class PlotTest(PlotTestBase):
     _, psID = PlotController.AddCurve(x*1.0e6, y*1.0e6, curve_label="titi", append=False)
     PlotController.SetYSciNotation(psID, True)
     self.assertTrue(self.areScreenshotEqual(tw))
-  
+
   def testRegisterCallback(self):
     global a_callb
     a_callb = 0
@@ -466,7 +464,7 @@ class PlotTest(PlotTestBase):
     PlotController.SetCurrentCurve(crvId)
     _, _ = PlotController.AddCurve(x, y)
     self.assertEqual(crvId, a_callb)
-    
+
   def testAddCurveEmptyPs(self):
     """ Adding a curve when no ps was active was buggy """
     self.showTabWidget()
@@ -478,7 +476,7 @@ class PlotTest(PlotTestBase):
     PlotController.AddCurve(x, y, append=True)
     l, _ = PlotController.GetAllPlotSets()
     self.assertEqual(2, len(l))
-    
+
   def test_onCurrentCurveChange(self):
     self.showTabWidget()
     x, y = self.generateSine()
@@ -517,10 +515,10 @@ class PlotTest(PlotTestBase):
     self.assertEqual(psID0, psID2)
     l, _ = PlotController.GetAllPlotSets()
     self.assertEqual(1, len(l))
-    
+
 # Even if not in main:
 processDecorator(__name__)
 
 if __name__ == "__main__":
-  import unittest    
+  import unittest
   unittest.main()
index a52511cd2ddadb6ee50c6c44964afc117897b941..ccdbc24b415f7a1e2206f0ccb3c6dacf07fc4ef1 100644 (file)
@@ -36,5 +36,10 @@ SET(_all_lib_SCRIPTS
 # --- rules ---
 SALOME_INSTALL_SCRIPTS("${_pyuic_SCRIPTS}" ${SALOME_CURVEPLOT_INSTALL_PYTHON})
 SALOME_INSTALL_SCRIPTS("${_all_lib_SCRIPTS}" ${SALOME_CURVEPLOT_INSTALL_PYTHON})
-
 INSTALL(FILES ${_pyuic_files} DESTINATION ${SALOME_CURVEPLOT_INSTALL_PYTHON})
+
+# For test purposes
+FILE(COPY ${_pyuic_SCRIPTS} DESTINATION ${CRVPLOT_TEST_INSTALL})
+FILE(COPY ${_pyuic_files} DESTINATION ${CRVPLOT_TEST_INSTALL})
+FILE(COPY ${_all_lib_SCRIPTS} DESTINATION ${CRVPLOT_TEST_INSTALL})
+
index bda0f5decd80176c4c30ac99543c92ff5afba411..d6b6d226395ad5987cd06290ecdd0650cc353542 100644 (file)
@@ -1,10 +1,10 @@
-from pyqtside import QtGui, QtCore
+from pyqtside import QtWidgets, QtCore
 from pyqtside.uic import loadUiGen
-from utils import completeResPath
+from .utils import completeResPath
 
-class CurveTreeDockWidget(QtGui.QDockWidget):
+class CurveTreeDockWidget(QtWidgets.QDockWidget):
   def __init__(self):
-    QtGui.QDockWidget.__init__(self)
+    QtWidgets.QDockWidget.__init__(self)
     loadUiGen(completeResPath("CurveTreeDockWidget.ui"), self)
     self.treeWidget.setHeaderLabel ("Plots")
     self.treeWidget.sortByColumn(0, QtCore.Qt.AscendingOrder)
index d264618953c992532a1d0eb768a50fee9c4f8f94..201e5074ea697e2b054749e450f57c39d2214138 100644 (file)
@@ -1,10 +1,12 @@
-from pyqtside import QtGui, QtCore
+from pyqtside.QtWidgets import QDialog, QColorDialog, QMessageBox
+from pyqtside.QtGui import QIcon, QPixmap, QColor
+from pyqtside.QtCore import pyqtSlot 
 from pyqtside.uic import loadUiGen
-from utils import completeResPath
+from .utils import completeResPath
 
-class PlotSettings(QtGui.QDialog):
+class PlotSettings(QDialog):
   def __init__(self):
-    QtGui.QDialog.__init__(self)
+    QDialog.__init__(self)
     loadUiGen(completeResPath("PlotSettings.ui"), self)
     self.initialize()
 
@@ -15,16 +17,16 @@ class PlotSettings(QtGui.QDialog):
     self._g = 0
     self._b = 1
    
-  @QtCore.Slot(int)
+  @pyqtSlot(int)
   def onShowLegend(self, index):
     if index > 0 :
       self.legendPositionComboBox.setEnabled(True)
     else :
       self.legendPositionComboBox.setEnabled(False)
   
-  @QtCore.Slot() 
+  @pyqtSlot() 
   def onChangeColor(self):
-    col = QtGui.QColorDialog.getColor()
+    col = QColorDialog.getColor()
 
     if col.isValid():
       r, g, b = [c/255.0 for c in col.getRgb()[:3]]
@@ -41,14 +43,14 @@ class PlotSettings(QtGui.QDialog):
     self._r = r
     self._g = g
     self._b = b
-    self.colorCurve.setIcon(QtGui.QIcon(self.drawColorPixmap(int(r*255), int(g*255), int(b*255))))
+    self.colorCurve.setIcon(QIcon(self.drawColorPixmap(int(r*255), int(g*255), int(b*255))))
    
   def getRGB(self):
     return self._r, self._g, self._b
    
   def drawColorPixmap(self, r, g, b):
-    pix = QtGui.QPixmap( 16, 16 )
-    color = QtGui.QColor(r, g, b)
+    pix = QPixmap( 16, 16 )
+    color = QColor(r, g, b)
     pix.fill(color)
     return pix
 
@@ -58,32 +60,32 @@ class PlotSettings(QtGui.QDialog):
     yminText = str(self.axisYMinEdit.text())
     ymaxText = str(self.axisYMaxEdit.text())
     if (yminText == "" or ymaxText == "") :
-      QtGui.QMessageBox.critical(self, "Plot settings", "A field \"YMin\" or \"YMax\" is empty")
+      QMessageBox.critical(self, "Plot settings", "A field \"YMin\" or \"YMax\" is empty")
     else :
       try:
         xmin = float(xminText)
       except ValueError:
-        QtGui.QMessageBox.critical(self, "Plot settings", "It is not possible to convert XMin")
+        QMessageBox.critical(self, "Plot settings", "It is not possible to convert XMin")
       try:
         xmax = float(xmaxText)
       except ValueError:
-        QtGui.QMessageBox.critical(self, "Plot settings", "It is not possible to convert XMax")
+        QMessageBox.critical(self, "Plot settings", "It is not possible to convert XMax")
       try:
         ymin = float(yminText)
       except ValueError:
-        QtGui.QMessageBox.critical(self, "Plot settings", "It is not possible to convert YMin")
+        QMessageBox.critical(self, "Plot settings", "It is not possible to convert YMin")
       try:
         ymax = float(ymaxText)
       except ValueError:
-        QtGui.QMessageBox.critical(self, "Plot settings", "It is not possible to convert YMax")
+        QMessageBox.critical(self, "Plot settings", "It is not possible to convert YMax")
       if ((xmax-xmin) == 0) :
-        QtGui.QMessageBox.critical(self, "Plot settings", "XMax is is equal to XMin.")
+        QMessageBox.critical(self, "Plot settings", "XMax is is equal to XMin.")
         return
       if ((ymax-ymin) == 0) :
-        QtGui.QMessageBox.critical(self, "Plot settings", "YMax is is equal to YMin.")
+        QMessageBox.critical(self, "Plot settings", "YMax is is equal to YMin.")
         return
       if ((xmax-xmin) < 0) :
-        QtGui.QMessageBox.warning(self, "Plot settings", "XMax is less than XMin.")
+        QMessageBox.warning(self, "Plot settings", "XMax is less than XMin.")
       if ((ymax-ymin) < 0) :
-        QtGui.QMessageBox.warning(self, "Plot settings", "YMax is less than YMin.")
+        QMessageBox.warning(self, "Plot settings", "YMax is less than YMin.")
       super(PlotSettings, self).accept()
index 677c5496a7769460139e23cc400859f6841f50d7..7a8a87fa4c516532b0d6edd7b24f1f16a9dc6674 100644 (file)
@@ -1,10 +1,10 @@
-from pyqtside import QtGui
+from pyqtside import QtWidgets
 from pyqtside.uic import loadUiGen
-from utils import completeResPath
+from .utils import completeResPath
 
-class PlotWidget(QtGui.QMainWindow):
+class PlotWidget(QtWidgets.QMainWindow):
   def __init__(self):
-    QtGui.QMainWindow.__init__(self)
+    QtWidgets.QMainWindow.__init__(self)
     loadUiGen(completeResPath("PlotWidget.ui"), self)
     
   def clearAll(self):
index 7186c1978d595d5ef1ff06033e6b61b19b742ad1..2f278d1c04d5fa4486112e899ff3d7d04c790eb4 100644 (file)
@@ -24,5 +24,8 @@ SET(_all_lib_SCRIPTS
     CurveView.py
     XYView.py
 )
-    
+
 SALOME_INSTALL_SCRIPTS("${_all_lib_SCRIPTS}" ${SALOME_CURVEPLOT_INSTALL_PYTHON})
+
+# For test purposes
+FILE(COPY ${_all_lib_SCRIPTS} DESTINATION ${CRVPLOT_TEST_INSTALL})
index df296b60a68525ebdbe8295ac27efd748f17ebdb..673ef2415edbb74855b2458cd77bf0fdffd85a13 100644 (file)
@@ -1,10 +1,10 @@
-from pyqtside import QtGui
-from pyqtside.QtGui import QMenu
+from pyqtside import QtWidgets
+from pyqtside.QtWidgets import QMenu
 from pyqtside.QtCore import Qt
 
-from View import View
-from CurveTreeDockWidget import CurveTreeDockWidget
-from utils import Logger
+from .View import View
+from .CurveTreeDockWidget import CurveTreeDockWidget
+from .utils import Logger
 
 class CurveBrowserView( View, CurveTreeDockWidget) :
 
@@ -36,10 +36,10 @@ class CurveBrowserView( View, CurveTreeDockWidget) :
             
         # The second (hidden) column in the tree bares the ID of the object and its nature (plotset or curve)
         for p in list(plotSets.values()):
-          item = QtGui.QTreeWidgetItem([str(p.getTitle()), str(p.getID()) + '_set'])
+          item = QtWidgets.QTreeWidgetItem([str(p.getTitle()), str(p.getID()) + '_set'])
           treeWidget.addTopLevelItem(item)
           for c in list(p._curves.values()):
-            chld = QtGui.QTreeWidgetItem([str(c.getTitle()), str(c.getID()) + '_crv'])
+            chld = QtWidgets.QTreeWidgetItem([str(c.getTitle()), str(c.getID()) + '_crv'])
             item.addChild(chld)
           
         treeWidget.expandAll()
index 9189239f9e66a386420c57ff10ae60485ca89760..46f8224bf3e7a8744292001db6b64774c8185bbc 100644 (file)
@@ -1,6 +1,6 @@
-from View import View
-from XYView import XYView
-from utils import Logger
+from .View import View
+from .XYView import XYView
+from .utils import Logger
 
 class CurveTabsView(View):
   def __init__(self, controller):
index 39ae897f1883fc4c5a9df79c775edfc578bc8b3c..ddf27334f109b64fb7c4072471ff7705cd48c08c 100644 (file)
@@ -1,5 +1,5 @@
-from View import View
-from utils import Logger
+from .View import View
+from .utils import Logger
 
 class CurveView(View):
   _PICKER_PRECISION = 20  #pts
index ba3ca573148c3977f275c86af9847e1d47c43655..3c64d7d78db7e2b8e7a1059f42eddd770f5802eb 100644 (file)
@@ -1,15 +1,15 @@
 import matplotlib.pyplot as plt
 import matplotlib.colors as colors
-from View import View
-from CurveView import CurveView
-
-from utils import Logger, trQ
-from PlotWidget import PlotWidget
-from PlotSettings import PlotSettings
-from pyqtside import QtGui, QtCore
+from pyqtside import QtWidgets, QtCore
 from pyqtside.QtCore import QObject
 from matplotlib.figure import Figure
-from matplotlib.backends.backend_qt4agg import FigureCanvasQTAgg, NavigationToolbar2QT
+from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg, NavigationToolbar2QT
+
+from .View import View
+from .CurveView import CurveView
+from .PlotWidget import PlotWidget
+from .PlotSettings import PlotSettings
+from .utils import Logger, trQ
 
 class EventHandler(QObject):
   """ Handle the right-click properly so that it only triggers the contextual menu """
@@ -182,7 +182,7 @@ class XYView(View):
     self._toolbar = self._plotWidget.toolBar
     self.populateToolbar()
 
-    self._popupMenu = QtGui.QMenu()
+    self._popupMenu = QtWidgets.QMenu()
     self._popupMenu.addAction(self._actionLegend)
 
     # Connect evenement for the graphic scene
@@ -208,7 +208,7 @@ class XYView(View):
     self._panAction.setCheckable(True)
     self._toolbar.addSeparator()
     # Actions to change the representation of curves
-    self._curveActionGroup = QtGui.QActionGroup(self._plotWidget)
+    self._curveActionGroup = QtWidgets.QActionGroup(self._plotWidget)
     self._pointsAction = self.createAndAddLocalAction("draw_points.png", trQ("DRAW_POINTS_TXT"))
     self._pointsAction.setCheckable(True)
     self._linesAction = self.createAndAddLocalAction("draw_lines.png", trQ("DRAW_LINES_TXT"))
@@ -220,7 +220,7 @@ class XYView(View):
     self._curveActionGroup.setExclusive(True)
     self._toolbar.addSeparator()
     # Actions to draw horizontal curves as linear or logarithmic
-    self._horActionGroup = QtGui.QActionGroup(self._plotWidget)
+    self._horActionGroup = QtWidgets.QActionGroup(self._plotWidget)
     self._horLinearAction = self.createAndAddLocalAction("hor_linear.png", trQ("HOR_LINEAR_TXT"))
     self._horLinearAction.setCheckable(True)
     self._horLogarithmicAction = self.createAndAddLocalAction("hor_logarithmic.png", trQ("HOR_LOGARITHMIC_TXT"))
@@ -231,7 +231,7 @@ class XYView(View):
     self._horActionGroup.triggered.connect(self.onViewHorizontalMode)
     self._toolbar.addSeparator()
     # Actions to draw vertical curves as linear or logarithmic
-    self._verActionGroup = QtGui.QActionGroup(self._plotWidget)
+    self._verActionGroup = QtWidgets.QActionGroup(self._plotWidget)
     self._verLinearAction = self.createAndAddLocalAction("ver_linear.png", trQ("VER_LINEAR_TXT"))
     self._verLinearAction.setCheckable(True)
     self._verLogarithmicAction = self.createAndAddLocalAction("ver_logarithmic.png", trQ("VER_LOGARITHMIC_TXT"))
@@ -264,7 +264,7 @@ class XYView(View):
                                         filters,
                                         trQ("DUMP_VIEW_FILE"),
                                         False )
-    name = str(fileName)
+    name = str(fileName[0])
     if name != "":
       self._mplAxes.figure.savefig(name)
     pass
@@ -609,7 +609,7 @@ class XYView(View):
 
     if not len(self._curveViews):
       # Reset color cycle
-      self._mplAxes.set_color_cycle(None)
+      self._mplAxes.set_prop_cycle(None)
 
     for a in added:
       self.appendCurve(a)