From 963d72a615df404c5522b31212a908532dc87eff Mon Sep 17 00:00:00 2001 From: rnv Date: Tue, 26 Jan 2016 17:48:46 +0300 Subject: [PATCH] PyQt5/PyQt4 support --- CMakeLists.txt | 2 + src/GUI_PY/CMakeLists.txt | 8 +- src/GUI_PY/dockwidgets.py | 5 +- src/GUI_PY/genericdialog.py | 7 +- src/GUI_PY/qtsalome.py.in | 129 +++++++++++++++++++++++++ src/GUI_PY/selectvars.py | 62 ++++++------ src/SalomeApp/salome_pluginsmanager.py | 25 ++--- 7 files changed, 187 insertions(+), 51 deletions(-) create mode 100644 src/GUI_PY/qtsalome.py.in diff --git a/CMakeLists.txt b/CMakeLists.txt index da2d2b5cf..9a4d53e52 100755 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -152,8 +152,10 @@ ENDIF() IF(NOT SALOME_BUILD_WITH_QT5) FIND_PACKAGE(SalomeQt4 REQUIRED COMPONENTS QtCore QtGui QtXml QtWebKit QtOpenGL QtNetwork) ADD_DEFINITIONS("-DUSE_SALOME_STYLE") + SET(QT_SALOME_VERSION 4) ELSE() FIND_PACKAGE(SalomeQt5 REQUIRED) + SET(QT_SALOME_VERSION 5) ENDIF() # PyQt diff --git a/src/GUI_PY/CMakeLists.txt b/src/GUI_PY/CMakeLists.txt index ff4ebe3bf..5c1a8d9fd 100755 --- a/src/GUI_PY/CMakeLists.txt +++ b/src/GUI_PY/CMakeLists.txt @@ -46,11 +46,17 @@ SET(_bin_SCRIPTS test_dockwidgets.py ) +SALOME_CONFIGURE_FILE(qtsalome.py.in qtsalome.py) + +SET(_gen_SCRIPTS + ${CMAKE_CURRENT_BINARY_DIR}/qtsalome.py +) + # scripts / to install SET(_all_SCRIPTS ${_other_SCRIPTS} ${_pyuic_SCRIPTS}) # --- rules --- - +SALOME_INSTALL_SCRIPTS("${_gen_SCRIPTS}" ${SALOME_INSTALL_PYTHON}) SALOME_INSTALL_SCRIPTS("${_all_SCRIPTS}" ${SALOME_INSTALL_PYTHON}/salome/gui) SALOME_INSTALL_SCRIPTS("${_bin_SCRIPTS}" ${SALOME_INSTALL_SCRIPT_DATA}) diff --git a/src/GUI_PY/dockwidgets.py b/src/GUI_PY/dockwidgets.py index 8bd579758..2d370e905 100644 --- a/src/GUI_PY/dockwidgets.py +++ b/src/GUI_PY/dockwidgets.py @@ -1,5 +1,4 @@ -from PyQt4.QtCore import * -from PyQt4.QtGui import * +from qtsalome import * import SalomePyQt @@ -25,7 +24,7 @@ def findDockWidgetByTitle( title ): """ sg = SalomePyQt.SalomePyQt() dwl = sg.getDesktop().findChildren( QDockWidget ) - dw = filter(lambda a: a.windowTitle() == QString( title ), dwl) + dw = filter(lambda a: a.windowTitle() == str( title ), dwl) if dw: return dw[0] return None diff --git a/src/GUI_PY/genericdialog.py b/src/GUI_PY/genericdialog.py index 9be5cee62..0fea2f25b 100644 --- a/src/GUI_PY/genericdialog.py +++ b/src/GUI_PY/genericdialog.py @@ -21,7 +21,7 @@ __author__="gboulant" __date__ ="$31 mars 2010 17:09:53$" -from PyQt4.QtGui import QDialog, QMessageBox +from qtsalome import QDialog, QMessageBox from genericdialog_ui import Ui_GenericDialog @@ -113,10 +113,9 @@ class GenericDialog(QDialog): # def TEST_GenericDialog(): import sys - from PyQt4.QtGui import QApplication - from PyQt4.QtCore import QObject, SIGNAL, SLOT + from qtsalome import QApplication, Connect app = QApplication(sys.argv) - QObject.connect(app, SIGNAL("lastWindowClosed()"), app, SLOT("quit()")) + Connect(app, "lastWindowClosed()", app, "quit()") dlg=GenericDialog() dlg.displayAndWait() diff --git a/src/GUI_PY/qtsalome.py.in b/src/GUI_PY/qtsalome.py.in new file mode 100644 index 000000000..bca637e8b --- /dev/null +++ b/src/GUI_PY/qtsalome.py.in @@ -0,0 +1,129 @@ +# -*- coding: utf-8 -*- +# Copyright (C) 2007-2015 CEA/DEN, EDF R&D, OPEN CASCADE +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# +# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +# + +QT_SALOME_VERSION=@QT_SALOME_VERSION@ + +try: + from PyQt@QT_SALOME_VERSION@.Qt import * +except: + pass + +__CONNECT__ = 0 +__DISCONNECT__ = 1 + +def Connect(*args): + """ + Connects signal of sender to slot of reciever or function. + + Examples: + + 1. Connect(sender, signal, reciever, slot) + - sender: sender of the signal + - signal: string value in the form 'signal_name(type1,type2,...)' + - reciever: reciever of the signal + - slot: string value in the form 'slot_name(type1,type2,...)' + + 2. Connect(sender, signal, function) + - sender: sender of the signal + - signal: string value in the form 'signal_name(type1,type2,...)' + - function: function instance + """ + if len(args) == 4: + _process(args[0], args[1], args[2], args[3], __CONNECT__) + elif len(args) == 3: + _process(args[0], args[1], None, args[2], __CONNECT__) + else: + RuntimeError("Bad number of arguments, expected 3 or 4 !!!") + +def Disconnect(*args): + """ + Disconnects signal of sender to slot of reciever or function. + + Examples: + + 1. Disconnect(sender, signal, reciever, slot) + - sender: sender of the signal + - signal: string value in the form 'signal_name(type1,type2,...)' + - reciever: reciever of the signal + - slot: string value in the form 'slot_name(type1,type2,...)' + + 2. Disconnect(sender, signal, function) + - sender: sender of the signal + - signal: string value in the form 'signal_name(type1,type2,...)' + - function: function instance + """ + if len(args) == 4: + _process(args[0], args[1], args[2], args[3], __DISCONNECT__) + elif len(args) == 3: + _process(args[0], args[1], None, args[2], __DISCONNECT__) + else: + RuntimeError("Bad number of arguments, expected 3 or 4 !!!") + +def _process(sender,signal,reciever,slot,operation): + isFunc = False + slotname = "" + if isinstance(slot, str): + n = slot.find("(") + if n > 0: + slotname = slot[:n] + + if callable(slot): + isFunc = True + + if QT_SALOME_VERSION == 4: + _call = None + if operation == __CONNECT__: + _call = QObject.connect + elif operation == __DISCONNECT__: + _call = QObject.disconnect + if isFunc: + _call(sender,SIGNAL(signal),slot) + else: + _call(sender,SIGNAL(signal),reciever,SLOT(slot)) + else: + signame = "" + n = signal.find("(") + if n > 0: + signame = signal[:n] + + tmp = signal[(n+1):] + m = tmp.rfind(")") + types = tmp[:m] + + if len(signame) > 0 and (len(slotname) > 0 or isFunc): + arg1 = "" + arg2 = "" + op = "" + rcv = "" + if len(types.strip()) > 0: + arg1 = "[" + types + "]" + if operation == __DISCONNECT__: + op = "dis" + if reciever is not None and not isFunc: + rcv= "reciever." + if isFunc: + arg2 = "slot" + else: + arg2 = slotname + + command = "sender." + signame + arg1 + "." + op + "connect(" + rcv + arg2 + ")" + exec(command) + else: + raise RuntimeError("Bad signal '%s' or slot '%s' format !!!"%(signal, slot)) diff --git a/src/GUI_PY/selectvars.py b/src/GUI_PY/selectvars.py index 412b6b82b..d7a1cb416 100644 --- a/src/GUI_PY/selectvars.py +++ b/src/GUI_PY/selectvars.py @@ -21,8 +21,8 @@ # import os -from PyQt4 import QtGui, QtCore -from PyQt4.QtCore import Qt + +from qtsalome import * import salome from salome.kernel.studyedit import getStudyEditor @@ -34,23 +34,23 @@ from salome.kernel.parametric import study_exchange_vars from SelectVarsDialog_ui import Ui_SelectVarsDialog -class MySelectVarsDialog(Ui_SelectVarsDialog, QtGui.QDialog): +class MySelectVarsDialog(Ui_SelectVarsDialog, QDialog): def __init__(self, parent = None, modal = 0): - QtGui.QDialog.__init__(self, parent) + QDialog.__init__(self, parent) Ui_SelectVarsDialog.__init__(self) self.setupUi(self) - self.connect(self.cancelButton, QtCore.SIGNAL("clicked()"), self.close) - self.connect(self.OKButton, QtCore.SIGNAL("clicked()"), self.accept) - self.connect(self.selectButton, QtCore.SIGNAL("clicked()"), self.initPotentialVariablesFromSelection) - self.connect(self.addInputVarButton, QtCore.SIGNAL("clicked()"), self.addSelectedInputVar) - self.connect(self.removeInputVarButton, QtCore.SIGNAL("clicked()"), self.removeSelectedInputVar) - self.connect(self.newInputVarButton, QtCore.SIGNAL("clicked()"), self.newInputVar) - self.connect(self.addOutputVarButton, QtCore.SIGNAL("clicked()"), self.addSelectedOutputVar) - self.connect(self.removeOutputVarButton, QtCore.SIGNAL("clicked()"), self.removeSelectedOutputVar) - self.connect(self.newOutputVarButton, QtCore.SIGNAL("clicked()"), self.newOutputVar) - self.connect(self.loadVarsButton, QtCore.SIGNAL("clicked()"), self.loadVars) - self.connect(self.saveVarsButton, QtCore.SIGNAL("clicked()"), self.saveVars) + Connect(self.cancelButton, "clicked()", self.close) + Connect(self.OKButton,"clicked()", self.accept) + Connect(self.selectButton, "clicked()", self.initPotentialVariablesFromSelection) + Connect(self.addInputVarButton, "clicked()", self.addSelectedInputVar) + Connect(self.removeInputVarButton, "clicked()", self.removeSelectedInputVar) + Connect(self.newInputVarButton, "clicked()", self.newInputVar) + Connect(self.addOutputVarButton, "clicked()", self.addSelectedOutputVar) + Connect(self.removeOutputVarButton, "clicked()", self.removeSelectedOutputVar) + Connect(self.newOutputVarButton, "clicked()", self.newOutputVar) + Connect(self.loadVarsButton, "clicked()", self.loadVars) + Connect(self.saveVarsButton, "clicked()", self.saveVars) self.refEntry = None def setExchangeVariables(self, exchangeVariables): @@ -62,8 +62,8 @@ class MySelectVarsDialog(Ui_SelectVarsDialog, QtGui.QDialog): def initPotentialVariablesFromSelection(self): entries = salome.sg.getAllSelected() if len(entries) != 1 : - QtGui.QMessageBox.warning(self, self.tr("Error"), - self.tr("One item must be selected in the object browser")) + QMessageBox.warning(self, self.tr("Error"), + self.tr("One item must be selected in the object browser")) return selectedEntry = entries[0] self._initPotentialVariables(selectedEntry) @@ -71,13 +71,13 @@ class MySelectVarsDialog(Ui_SelectVarsDialog, QtGui.QDialog): def _initPotentialVariables(self, entry): sobj = getStudyEditor().study.FindObjectID(entry) if sobj is None: - QtGui.QMessageBox.warning(self, self.tr("Error"), - self.tr('No item at entry %s' % entry)) + QMessageBox.warning(self, self.tr("Error"), + self.tr('No item at entry %s' % entry)) return exchangeVariables = study_exchange_vars.getExchangeVariablesFromSObject(sobj) if exchangeVariables is None: - QtGui.QMessageBox.warning(self, self.tr("Error"), - self.tr('Item at entry %s is not a valid ' + QMessageBox.warning(self, self.tr("Error"), + self.tr('Item at entry %s is not a valid ' '"Variable List" object' % entry)) return self.refEntry = entry @@ -89,27 +89,27 @@ class MySelectVarsDialog(Ui_SelectVarsDialog, QtGui.QDialog): def addSelectedInputVar(self): for item in self.allInputVarListWidget.selectedItems(): - self.selectedInputVarListWidget.addItem(QtGui.QListWidgetItem(item)) + self.selectedInputVarListWidget.addItem(QListWidgetItem(item)) def removeSelectedInputVar(self): for item in self.selectedInputVarListWidget.selectedItems(): self.selectedInputVarListWidget.takeItem(self.selectedInputVarListWidget.row(item)) def newInputVar(self): - newItem = QtGui.QListWidgetItem("TO EDIT!") + newItem = QListWidgetItem("TO EDIT!") newItem.setFlags(Qt.ItemIsSelectable|Qt.ItemIsEditable|Qt.ItemIsUserCheckable|Qt.ItemIsEnabled) self.selectedInputVarListWidget.addItem(newItem); def addSelectedOutputVar(self): for item in self.allOutputVarListWidget.selectedItems(): - self.selectedOutputVarListWidget.addItem(QtGui.QListWidgetItem(item)) + self.selectedOutputVarListWidget.addItem(QListWidgetItem(item)) def removeSelectedOutputVar(self): for item in self.selectedOutputVarListWidget.selectedItems(): self.selectedOutputVarListWidget.takeItem(self.selectedOutputVarListWidget.row(item)) def newOutputVar(self): - newItem = QtGui.QListWidgetItem("TO EDIT!") + newItem = QListWidgetItem("TO EDIT!") newItem.setFlags(Qt.ItemIsSelectable|Qt.ItemIsEditable|Qt.ItemIsUserCheckable|Qt.ItemIsEnabled) self.selectedOutputVarListWidget.addItem(newItem); @@ -125,7 +125,7 @@ class MySelectVarsDialog(Ui_SelectVarsDialog, QtGui.QDialog): return study_exchange_vars.ExchangeVariables(inputVarList, outputVarList, self.refEntry) def loadVars(self): - filename = QtGui.QFileDialog.getOpenFileName(self, self.tr("Import variables from file"), + filename = QFileDialog.getOpenFileName(self, self.tr("Import variables from file"), os.getenv("HOME"), self.tr("XML Files (*.xml)")) if not filename: @@ -135,12 +135,12 @@ class MySelectVarsDialog(Ui_SelectVarsDialog, QtGui.QDialog): exchange_variables = study_exchange_vars.loadExchangeVariablesFromXmlFile(filename) self.setExchangeVariables(exchange_variables) except Exception, e: - QtGui.QMessageBox.critical(self, self.tr("Error"), - self.tr("Cannot load file %s:\n%s" % (filename, e))) + QMessageBox.critical(self, self.tr("Error"), + self.tr("Cannot load file %s:\n%s" % (filename, e))) def saveVars(self): default = os.path.join(os.getenv("HOME"), "vars.xml") - filename = QtGui.QFileDialog.getSaveFileName(self, self.tr("Export variables to file"), + filename = QFileDialog.getSaveFileName(self, self.tr("Export variables to file"), default, self.tr("XML Files (*.xml)")) if not filename: return @@ -149,5 +149,5 @@ class MySelectVarsDialog(Ui_SelectVarsDialog, QtGui.QDialog): exchange_variables = self.getSelectedExchangeVariables() exchange_variables.saveToXmlFile(filename) except Exception, e: - QtGui.QMessageBox.critical(self, self.tr("Error"), - self.tr("Cannot save file %s:\n%s" % (filename, e))) + QMessageBox.critical(self, self.tr("Error"), + self.tr("Cannot save file %s:\n%s" % (filename, e))) diff --git a/src/SalomeApp/salome_pluginsmanager.py b/src/SalomeApp/salome_pluginsmanager.py index 482d9d3ee..fd07afd79 100644 --- a/src/SalomeApp/salome_pluginsmanager.py +++ b/src/SalomeApp/salome_pluginsmanager.py @@ -44,7 +44,7 @@ name salome_plugins.py (example follows):: import salome_pluginsmanager def about(context): - from PyQt4.QtGui import QMessageBox + from qtsalome import QMessageBox QMessageBox.about(None, "About SALOME pluginmanager", "SALOME plugins manager in SALOME virtual application ") salome_pluginsmanager.AddFunction('About plugins','About SALOME pluginmanager',about) @@ -83,8 +83,7 @@ context attributes: """ import os,sys,traceback -from PyQt4 import QtGui -from PyQt4 import QtCore +from qtsalome import * import salome @@ -124,13 +123,15 @@ class Context: def find_menu(smenu): lmenus=smenu.split("|") - main=lmenus.takeFirst().trimmed() + # Take first element from the list + main=lmenus.pop(0).strip() menu=sgPyQt.getPopupMenu(main) return findMenu(lmenus,menu) def findMenu(lmenu,menu): if not lmenu:return menu - m=lmenu.takeFirst().trimmed() + # Take first element from the list + m=lmenu.pop(0).strip() for a in menu.actions(): if a.menu(): if a.text() == m: @@ -148,8 +149,8 @@ logger=Logger("PluginsManager") #,color=GREEN) class PluginsManager: def __init__(self,module,name,basemenuname,menuname): self.name=name - self.basemenuname=QtCore.QString.fromUtf8(basemenuname) - self.menuname=QtCore.QString.fromUtf8(menuname) + self.basemenuname=unicode(basemenuname) + self.menuname=unicode(menuname) self.module=module self.registry={} self.handlers={} @@ -198,15 +199,15 @@ class PluginsManager: self.basemenu = find_menu(self.basemenuname) if self.module: - self.menu=QtGui.QMenu(self.menuname) + self.menu=QMenu(self.menuname) mid=sgPyQt.createMenu(self.menu.menuAction(),self.basemenuname) else: - self.menu=QtGui.QMenu(self.menuname,self.basemenu) + self.menu=QMenu(self.menuname,self.basemenu) self.basemenu.addMenu(self.menu) self.menu.menuAction().setVisible(False) - self.basemenu.connect(self.basemenu, QtCore.SIGNAL("aboutToShow()"), self.importPlugins) + Connect(self.basemenu, "aboutToShow()", self.importPlugins) def analyseFile(self,filename): """ @@ -232,7 +233,7 @@ class PluginsManager: script(Context(sgPyQt)) except: s=traceback.format_exc() - QtGui.QMessageBox.warning(None,"Exception occured",s) + QMessageBox.warning(None,"Exception occured",s) self.handlers[name]=handler @@ -307,7 +308,7 @@ class PluginsManager: if submenus.has_key(name): amenu=submenus[name] else: - amenu=QtGui.QMenu(name,parentMenu) + amenu=QMenu(name,parentMenu) parentMenu.addMenu(amenu) submenus[name]=amenu parentMenu=amenu -- 2.39.2