From: rnv Date: Wed, 27 Jan 2016 15:34:03 +0000 (+0300) Subject: PyQt4/PyQt5 support: use new PyQt signals/slots approach, which has been introduced... X-Git-Tag: V8_0_0rc1~10 X-Git-Url: http://git.salome-platform.org/gitweb/?a=commitdiff_plain;h=c6008568a148c0f5a53b7bcb6b52e208c96e40e0;p=modules%2Fgui.git PyQt4/PyQt5 support: use new PyQt signals/slots approach, which has been introduced since PyQt-4.5 version and supported in the PyQt5. --- diff --git a/src/GUI_PY/genericdialog.py b/src/GUI_PY/genericdialog.py index 0fea2f25b..9c17e948b 100644 --- a/src/GUI_PY/genericdialog.py +++ b/src/GUI_PY/genericdialog.py @@ -113,9 +113,9 @@ class GenericDialog(QDialog): # def TEST_GenericDialog(): import sys - from qtsalome import QApplication, Connect + from qtsalome import QApplication app = QApplication(sys.argv) - Connect(app, "lastWindowClosed()", app, "quit()") + app.lastWindowClosed.connect(app.quit) dlg=GenericDialog() dlg.displayAndWait() diff --git a/src/GUI_PY/mytestdialog.py b/src/GUI_PY/mytestdialog.py index 24d057640..5309afa54 100644 --- a/src/GUI_PY/mytestdialog.py +++ b/src/GUI_PY/mytestdialog.py @@ -20,7 +20,7 @@ __author__="gboulant" __date__ ="$31 mars 2010 17:09:53$" - +from qtsalome import * from mytestdialog_ui import Ui_MyTestDialog from genericdialog import GenericDialog @@ -71,13 +71,15 @@ class MyTestDialog(GenericDialog): return name -from PyQt4.QtCore import SIGNAL class MyTestDialogWithSignals(MyTestDialog): """ This class is to illustrate the usage of the GenericDialog in the case where the dialog windows is not modal. In such a case, the controller must be warn of close events using Qt signals. """ + + inputValidated = pyqtSignal() + def __init__(self, parent=None, name="MyTestDialogWithSignals"): MyTestDialog.__init__(self, parent, name) @@ -92,7 +94,7 @@ class MyTestDialogWithSignals(MyTestDialog): # has been validated so that it can process the event MyTestDialog.accept(self) if self.wasOk(): - self.emit(SIGNAL('inputValidated()')) + self.inputValidated.emit() @@ -104,10 +106,9 @@ class MyTestDialogWithSignals(MyTestDialog): def TEST_MyTestDialog_modal(): import sys - from PyQt4.QtCore import QObject, SIGNAL, SLOT - from PyQt4.QtGui import QApplication + from qtsalome import QApplication app = QApplication(sys.argv) - QObject.connect(app, SIGNAL("lastWindowClosed()"), app, SLOT("quit()")) + app.lastWindowClosed.connect(app.quit) dlg=MyTestDialog() dlg.setData("A default name") @@ -126,10 +127,8 @@ class DialogListener: def TEST_MyTestDialog_non_modal(): import sys - from PyQt4.QtCore import QObject, SIGNAL, SLOT - from PyQt4.QtGui import QApplication app = QApplication(sys.argv) - QObject.connect(app, SIGNAL("lastWindowClosed()"), app, SLOT("quit()")) + app.lastWindowClosed.connect(app.quit) dlg=MyTestDialogWithSignals() # This dialog window will emit a inputValidated() signal when the @@ -137,7 +136,7 @@ def TEST_MyTestDialog_non_modal(): # connect this signal to a local slot so that the event can be # processed. dlgListener = DialogListener() - app.connect(dlg, SIGNAL('inputValidated()'), dlgListener.onProcessEvent) + dlg.inputValidated.connect(dlgListener.onProcessEvent) # This connect instruction means that the signal inputValidated() # emited by the dlg Qt object will raise a call to the slot # dlgListener.onProcessEvent diff --git a/src/GUI_PY/qtsalome.py.in b/src/GUI_PY/qtsalome.py.in index bca637e8b..d22dfe698 100644 --- a/src/GUI_PY/qtsalome.py.in +++ b/src/GUI_PY/qtsalome.py.in @@ -24,106 +24,3 @@ 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 d7a1cb416..113f66722 100644 --- a/src/GUI_PY/selectvars.py +++ b/src/GUI_PY/selectvars.py @@ -40,17 +40,17 @@ class MySelectVarsDialog(Ui_SelectVarsDialog, QDialog): QDialog.__init__(self, parent) Ui_SelectVarsDialog.__init__(self) self.setupUi(self) - 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.cancelButton.clicked.connect(self.close) + self.OKButton.clicked.connect(self.accept) + self.selectButton.clicked.connect(self.initPotentialVariablesFromSelection) + self.addInputVarButton.clicked.connect(self.addSelectedInputVar) + self.removeInputVarButton.clicked.connect(self.removeSelectedInputVar) + self.newInputVarButton.clicked.connect(self.newInputVar) + self.addOutputVarButton.clicked.connect(self.addSelectedOutputVar) + self.removeOutputVarButton.clicked.connect(self.removeSelectedOutputVar) + self.newOutputVarButton.clicked.connect( self.newOutputVar) + self.loadVarsButton.clicked.connect(self.loadVars) + self.saveVarsButtonself.clicked.connect(self.saveVars) self.refEntry = None def setExchangeVariables(self, exchangeVariables): diff --git a/src/SALOME_PYQT/SalomePyQt/SalomePyQt.sip b/src/SALOME_PYQT/SalomePyQt/SalomePyQt.sip index 0ab24632c..3690f86b9 100644 --- a/src/SALOME_PYQT/SalomePyQt/SalomePyQt.sip +++ b/src/SALOME_PYQT/SalomePyQt/SalomePyQt.sip @@ -43,6 +43,7 @@ #include #include #include +#include #include %End @@ -210,6 +211,32 @@ private: QtxActionGroup( const QtxActionGroup& ); }; +class QtxTreeView : public QTreeView +{ +%TypeHeaderCode +#include +%End + +%ConvertToSubClassCode + if ( qobject_cast( sipCpp ) ) + sipClass = sipClass_QtxTreeView; + else + sipClass = NULL; +%End + +public: + explicit QtxTreeView( QWidget* /TransferThis/ = 0 ); + QtxTreeView( const bool, QWidget* /TransferThis/ = 0 ); + virtual ~QtxTreeView(); + +signals: + void sortingEnabled( bool ); + void selectionChanged(); + +private: + QtxTreeView( const QtxTreeView& ); +}; + enum VisibilityState { ShownState, diff --git a/src/SalomeApp/pluginsdemo/CMakeLists.txt b/src/SalomeApp/pluginsdemo/CMakeLists.txt index 9e997c7f9..e0cb9e4bc 100755 --- a/src/SalomeApp/pluginsdemo/CMakeLists.txt +++ b/src/SalomeApp/pluginsdemo/CMakeLists.txt @@ -25,12 +25,25 @@ # variable *_ROOT_DIR). # +INCLUDE(UseQtExt) +INCLUDE(UsePyQt) + +# --- resources --- + +# uic files / to be processed by pyuic +SET(_pyuic_files + minmax.ui +) + +# scripts / pyuic wrappings +PYQT_WRAP_UIC(_pyuic_SCRIPTS ${_pyuic_files}) + # --- scripts --- # scripts / static # TODO: process UIC files via PyQt pyuic tool, see UsePyQt.cmake SET(_plugins_SCRIPTS - minmax_dialog.py + ${_pyuic_SCRIPTS} minmax_plugin.py trihedron.py tubedialog_ui.py diff --git a/src/SalomeApp/pluginsdemo/minmax_plugin.py b/src/SalomeApp/pluginsdemo/minmax_plugin.py index adc759426..b6470ff32 100644 --- a/src/SalomeApp/pluginsdemo/minmax_plugin.py +++ b/src/SalomeApp/pluginsdemo/minmax_plugin.py @@ -19,18 +19,15 @@ # # Author : Guillaume Boulant (EDF) +from qtsalome import * + def minmax(context): # get context study, studyId, salomeGui study = context.study studyId = context.studyId sg = context.sg - from PyQt4.QtGui import QDialog - from PyQt4.QtGui import QMessageBox - from PyQt4.QtCore import Qt - from PyQt4.QtCore import SIGNAL - - from minmax_dialog import Ui_Dialog + from minmax_ui import Ui_Dialog import salome import SMESH @@ -86,7 +83,7 @@ def minmax(context): self.clearLineEdit() # Connect up the selectionChanged() event of the object browser. - self.connect(sg.getObjectBrowser(), SIGNAL("selectionChanged()"), self.select) + sg.getObjectBrowser().selectionChanged.connect(self.select) self.mm = None self.ui.control.setFocus() @@ -95,7 +92,7 @@ def minmax(context): pass def OnCancel(self): - self.disconnect(sg.getObjectBrowser(), SIGNAL("selectionChanged()"), self.select) + sg.getObjectBrowser().selectionChanged.disconnect(self.select) self.reject() pass @@ -106,7 +103,7 @@ def minmax(context): self.ui.maxvalue.setText("") def select(self): - self.disconnect(sg.getObjectBrowser(), SIGNAL("selectionChanged()"), self.select) + sg.getObjectBrowser().selectionChanged.disconnect(self.select) self.ui.control.clear() self.ui.minvalue.setText("") self.ui.maxvalue.setText("") @@ -141,7 +138,7 @@ def minmax(context): pass self.ui.control.addItems(controls) self.compute_minmax() - self.connect(sg.getObjectBrowser(), SIGNAL("selectionChanged()"), self.select) + sg.getObjectBrowser().selectionChanged.connect(self.select) pass def helpMessage(self): diff --git a/src/SalomeApp/pluginsdemo/tubedialog.py b/src/SalomeApp/pluginsdemo/tubedialog.py index 9d1e8f5cb..3be3f16ee 100644 --- a/src/SalomeApp/pluginsdemo/tubedialog.py +++ b/src/SalomeApp/pluginsdemo/tubedialog.py @@ -19,8 +19,7 @@ # Author : Guillaume Boulant (EDF) import sys -from PyQt4 import QtGui -from PyQt4 import QtCore +from qtsalome import * from tubedialog_ui import TubeDialog_UI @@ -33,27 +32,27 @@ class TubeDialog(TubeDialog_UI): def handleAcceptWith(self,callbackFunction): """This defines the function to be connected to the signal 'accepted()' (click on Ok)""" - QtCore.QObject.connect(self.buttonBox, QtCore.SIGNAL("accepted()"), callbackFunction) + self.buttonBox.accepted.connect(callbackFunction) def handleRejectWith(self,callbackFunction): """This defines the function to be connected to the signal 'rejected()' (click on Cancel)""" - QtCore.QObject.connect(self.buttonBox, QtCore.SIGNAL("rejected()"), callbackFunction) + self.buttonBox.rejected.connect(callbackFunction) def handleApplyWith(self,callbackFunction): """This defines the function to be connected to the signal 'apply()' (click on Apply)""" - button = self.buttonBox.button(QtGui.QDialogButtonBox.Apply) - QtCore.QObject.connect(button, QtCore.SIGNAL("clicked()"), callbackFunction); + button = self.buttonBox.button(QDialogButtonBox.Apply) + button.clicked.connect(callbackFunction); def accept(self): '''Callback function when dialog is accepted (click Ok)''' self._wasOk = True # We should test here the validity of values - QtGui.QDialog.accept(self) + QDialog.accept(self) def reject(self): '''Callback function when dialog is rejected (click Cancel)''' self._wasOk = False - QtGui.QDialog.reject(self) + QDialog.reject(self) def wasOk(self): return self._wasOk @@ -83,13 +82,13 @@ class TubeDialogOnTopWithApply(TubeDialog): """ TubeDialog.setupUi(self) # Add a button "Apply" - self.buttonBox.setStandardButtons(QtGui.QDialogButtonBox.Cancel| - QtGui.QDialogButtonBox.Apply| - QtGui.QDialogButtonBox.Ok) + self.buttonBox.setStandardButtons(QDialogButtonBox.Cancel| + QDialogButtonBox.Apply| + QDialogButtonBox.Ok) # Keep the dialog on top of the windows self.setWindowFlags(self.windowFlags() | - QtCore.Qt.WindowStaysOnTopHint) + Qt.WindowStaysOnTopHint) # @@ -108,10 +107,9 @@ def TEST_getData_synchrone(): def main( args ): - a = QtGui.QApplication(sys.argv) + a = QApplication(sys.argv) TEST_getData_synchrone() sys.exit(0) if __name__=="__main__": main(sys.argv) - diff --git a/src/SalomeApp/pluginsdemo/tubedialog_ui.py b/src/SalomeApp/pluginsdemo/tubedialog_ui.py index 571e6c992..4c3f21a4d 100644 --- a/src/SalomeApp/pluginsdemo/tubedialog_ui.py +++ b/src/SalomeApp/pluginsdemo/tubedialog_ui.py @@ -20,69 +20,68 @@ # Author : Guillaume Boulant (EDF) import sys -from PyQt4 import QtGui -from PyQt4 import QtCore +from qtsalome import * -class TubeDialog_UI(QtGui.QDialog): +class TubeDialog_UI(QDialog): """ This class defines the design of a Qt dialog box dedicated to the salome plugin examples. It presents a UI form that contains parameters for the spatial dimensions of geometrical object. """ def __init__(self, parent=None): - QtGui.QDialog.__init__(self, parent) + QDialog.__init__(self, parent) self.setupUi() def setupUi(self): self.setObjectName("Dialog") self.resize(400, 300) - self.hboxlayout = QtGui.QHBoxLayout(self) - self.hboxlayout.setMargin(9) + self.hboxlayout = QHBoxLayout(self) + self.hboxlayout.setContentsMargins(9,9,9,9) self.hboxlayout.setSpacing(6) self.hboxlayout.setObjectName("hboxlayout") - self.vboxlayout = QtGui.QVBoxLayout() - self.vboxlayout.setMargin(0) + self.vboxlayout = QVBoxLayout() + self.vboxlayout.setContentsMargins(0,0,0,0) self.vboxlayout.setSpacing(6) self.vboxlayout.setObjectName("vboxlayout") - self.hboxlayout1 = QtGui.QHBoxLayout() - self.hboxlayout1.setMargin(0) + self.hboxlayout1 = QHBoxLayout() + self.hboxlayout1.setContentsMargins(0,0,0,0) self.hboxlayout1.setSpacing(6) self.hboxlayout1.setObjectName("hboxlayout1") - self.vboxlayout1 = QtGui.QVBoxLayout() - self.vboxlayout1.setMargin(0) + self.vboxlayout1 = QVBoxLayout() + self.vboxlayout1.setContentsMargins(0,0,0,0) self.vboxlayout1.setSpacing(6) self.vboxlayout1.setObjectName("vboxlayout1") - self.lblRadius = QtGui.QLabel(self) + self.lblRadius = QLabel(self) self.lblRadius.setObjectName("lblRadius") self.vboxlayout1.addWidget(self.lblRadius) - self.lblLength = QtGui.QLabel(self) + self.lblLength = QLabel(self) self.lblLength.setObjectName("lblLength") self.vboxlayout1.addWidget(self.lblLength) - self.lblWidth = QtGui.QLabel(self) + self.lblWidth = QLabel(self) self.lblWidth.setObjectName("lblWidth") self.vboxlayout1.addWidget(self.lblWidth) self.hboxlayout1.addLayout(self.vboxlayout1) - self.vboxlayout2 = QtGui.QVBoxLayout() - self.vboxlayout2.setMargin(0) + self.vboxlayout2 = QVBoxLayout() + self.vboxlayout2.setContentsMargins(0,0,0,0) self.vboxlayout2.setSpacing(6) self.vboxlayout2.setObjectName("vboxlayout2") - self.txtRadius = QtGui.QLineEdit(self) + self.txtRadius = QLineEdit(self) self.txtRadius.setObjectName("txtRadius") self.vboxlayout2.addWidget(self.txtRadius) - self.txtLength = QtGui.QLineEdit(self) + self.txtLength = QLineEdit(self) self.txtLength.setObjectName("txtLength") self.vboxlayout2.addWidget(self.txtLength) - self.txtWidth = QtGui.QLineEdit(self) + self.txtWidth = QLineEdit(self) self.txtWidth.setObjectName("txtWidth") self.vboxlayout2.addWidget(self.txtWidth) self.hboxlayout1.addLayout(self.vboxlayout2) self.vboxlayout.addLayout(self.hboxlayout1) - spacerItem = QtGui.QSpacerItem(20, 40, QtGui.QSizePolicy.Minimum, QtGui.QSizePolicy.Expanding) + spacerItem = QSpacerItem(20, 40, QSizePolicy.Minimum, QSizePolicy.Expanding) self.vboxlayout.addItem(spacerItem) - self.buttonBox = QtGui.QDialogButtonBox(self) - self.buttonBox.setOrientation(QtCore.Qt.Horizontal) - self.buttonBox.setStandardButtons(QtGui.QDialogButtonBox.Cancel|QtGui.QDialogButtonBox.NoButton|QtGui.QDialogButtonBox.Ok) + self.buttonBox = QDialogButtonBox(self) + self.buttonBox.setOrientation(Qt.Horizontal) + self.buttonBox.setStandardButtons(QDialogButtonBox.Cancel|QDialogButtonBox.NoButton|QDialogButtonBox.Ok) self.buttonBox.setObjectName("buttonBox") self.vboxlayout.addWidget(self.buttonBox) self.hboxlayout.addLayout(self.vboxlayout) @@ -98,10 +97,9 @@ class TubeDialog_UI(QtGui.QDialog): # ====================================================================== # def main( args ): - a = QtGui.QApplication(sys.argv) + a = QApplication(sys.argv) tubedialog = TubeDialog_UI() sys.exit(tubedialog.exec_()) if __name__=="__main__": main(sys.argv) - diff --git a/src/SalomeApp/salome_pluginsmanager.py b/src/SalomeApp/salome_pluginsmanager.py index fd07afd79..ba0dd119a 100644 --- a/src/SalomeApp/salome_pluginsmanager.py +++ b/src/SalomeApp/salome_pluginsmanager.py @@ -207,7 +207,7 @@ class PluginsManager: self.menu.menuAction().setVisible(False) - Connect(self.basemenu, "aboutToShow()", self.importPlugins) + self.basemenu.aboutToShow.connect(self.importPlugins) def analyseFile(self,filename): """