diff --git a/CMakeLists.txt b/CMakeLists.txt index 062fa8eb8..5505dbd9c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -66,6 +66,7 @@ OPTION(SALOME_BUILD_TESTS "Build SALOME tests" ON) # Advanced options: OPTION(SALOME_BUILD_GUI "Enable GUI" ON) +OPTION(SALOME_USE_PYSIDE "Use PySide2 to create Python bindings for Qt" ON) CMAKE_DEPENDENT_OPTION(SALOME_GEOM_USE_OPENCV "Enable shape recognition from picture" OFF "SALOME_BUILD_GUI" OFF) CMAKE_DEPENDENT_OPTION(SALOME_GEOM_USE_VTK "Enable VTK-dependent functionality" ON diff --git a/src/Tools/t_shape/CMakeLists.txt b/src/Tools/t_shape/CMakeLists.txt index a7467634f..013a194d6 100644 --- a/src/Tools/t_shape/CMakeLists.txt +++ b/src/Tools/t_shape/CMakeLists.txt @@ -43,7 +43,77 @@ IF(SALOME_BUILD_GUI) ) # scripts / pyuic wrappings - PYQT_WRAP_UIC(_pyuic_SCRIPTS ${_pyuic_FILES} TARGET_NAME _target_name_pyuic) + IF(SALOME_USE_PYSIDE) + + MESSAGE(STATUS "SALOME_USE_PYSIDE is defined. Start compilation with PySide2.") + + # ========================== Find PySide2 uic compiler ================= + + # In Qt for Python 5.14.0 pyside2-uic/pyside2-rcc was replaced by uic/rcc + # which now have an option to generate Python. + # So, the stuff below will work only with Qt for Python >= 5.14.0 + SET(uic_compiler_names + uic + ) + + SET(uic_compiler_hints + /usr/bin/uic + ) + + FIND_PROGRAM(uic_compiler NAMES ${uic_compiler_names} HINTS ${uic_compiler_hints}) + IF(uic_compiler) + MESSAGE(STATUS "Found PySide2 uic tool: ${uic_compiler}") + ELSE() + MESSAGE(FATAL_ERROR "Couldn't find PySide2 uic tool!") + ENDIF() + + # ========================== Generate Python class for each uic file ================= + + SET(_pyuic_SCRIPTS) + SET(_target_name_pyuic) + SET(uic_options -g python) + + FOREACH(uic_infile ${_pyuic_FILES}) + + # Make a file name + GET_FILENAME_COMPONENT(uic_outfile ${uic_infile} NAME) + STRING(REPLACE ".ui" "_ui.py" uic_outfile ${uic_outfile}) + SET(uic_outfile ${CMAKE_CURRENT_BINARY_DIR}/${uic_outfile}) + + # We need to use absolute path for a command + SET(uic_infile ${CMAKE_CURRENT_SOURCE_DIR}/${uic_infile}) + + SET(uic_command_options ${uic_options} -o ${uic_outfile} ${uic_infile}) + MESSAGE(STATUS "uic_command_options: ${uic_command_options}") + + # Create a command to call uic + ADD_CUSTOM_COMMAND( + OUTPUT ${uic_outfile} + COMMAND ${uic_compiler} ${uic_command_options} + MAIN_DEPENDENCY ${uic_infile} + VERBATIM + ) + + # Set additional properties + SET_SOURCE_FILES_PROPERTIES(${uic_infile} PROPERTIES SKIP_AUTOUIC ON) + SET_SOURCE_FILES_PROPERTIES(${uic_outfile} PROPERTIES SKIP_AUTOMOC ON) + SET_SOURCE_FILES_PROPERTIES(${uic_outfile} PROPERTIES SKIP_AUTOUIC ON) + + # Save the result + LIST(APPEND _pyuic_SCRIPTS ${uic_outfile}) + MESSAGE(STATUS "_pyuic_SCRIPTS: ${_pyuic_SCRIPTS}") + + # Make target name the same way as for PyQt + _PYQT_WRAP_GET_UNIQUE_TARGET_NAME(BUILD_UI_PY_FILES _target_name_pyuic_cur) + ADD_CUSTOM_TARGET(${_target_name_pyuic_cur} ALL DEPENDS ${${_pyuic_SCRIPTS}}) + + LIST(APPEND _target_name_pyuic ${_target_name_pyuic_cur}) + + ENDFOREACH() + + ELSE() + PYQT_WRAP_UIC(_pyuic_SCRIPTS ${_pyuic_FILES} TARGET_NAME _target_name_pyuic) + ENDIF() ENDIF() # --- rules --- diff --git a/src/Tools/t_shape/t_shape_dialog.py b/src/Tools/t_shape/t_shape_dialog.py index 7278f43c5..92ccbafc4 100644 --- a/src/Tools/t_shape/t_shape_dialog.py +++ b/src/Tools/t_shape/t_shape_dialog.py @@ -20,7 +20,18 @@ # Author : Renaud Nédélec (OpenCascade S.A.S) import sys -from qtsalome import * +import os + +# PySide testing +import SalomePyQt + +# Check if SalomePyQt uses PySide2 +use_pyside = False +if hasattr(SalomePyQt, 'use_pyside'): + from PySide2.QtWidgets import QWidget, QApplication + use_pyside = True +else: + from qtsalome import * from salome.geom.t_shape.t_shape_dialog_ui import Ui_Dialog @@ -39,7 +50,32 @@ class TShapeDialog(Ui_Dialog,QWidget): self.dsb_smallRadius.setValue(40.0) self.dsb_bigHeight.setValue(80.0) self.dsb_smallHeight.setValue(80.0) + + # PySide testing + self.dsb_getFileNameBtn.clicked.connect(self.get_file_name) + self.set_qt_bindings() + + def get_file_name(self): + """ + Updates displayed file name for testing PySide integration. + """ + salome_py_qt = SalomePyQt.SalomePyQt() + filename = salome_py_qt.getFileName(self, os.path.expanduser("~"), [], self.tr("Testing getting a file name with PySide"), True) + if not filename: + return + + self.dsb_fileName.setText(filename) + + def set_qt_bindings(self): + """ + Returns a name of packaged that used for Qt bindings. + This function is only for testing PySide integration. + """ + + qt_bindings = 'PySide2' if use_pyside else 'PyQt5' + self.dsb_qt_bindings_value.setText(qt_bindings) + def accept(self): from salome.geom.t_shape import t_shape_progress import xalome @@ -72,6 +108,21 @@ class TShapeDialog(Ui_Dialog,QWidget): return self._wasOk __dialog=None + +def update_pyside(dialog): + """ + This function updates displayed data for testing PySide integration. + """ + salome_py_qt = SalomePyQt.SalomePyQt() + + # Main frame width + main_frame_width = salome_py_qt.getMainFrame().width() + dialog.dsb_widthMainFrameValue.setText(str(main_frame_width)) + + # Components + components = salome_py_qt.getComponents() + dialog.dsb_components.addItems(components) + def getDialog(): """ This function returns a singleton instance of the plugin dialog. @@ -80,6 +131,8 @@ def getDialog(): global __dialog if __dialog is None: __dialog = TShapeDialog() + + update_pyside(__dialog) return __dialog # ================ diff --git a/src/Tools/t_shape/t_shape_dialog.ui b/src/Tools/t_shape/t_shape_dialog.ui index 9bc0affe2..b2913e02a 100644 --- a/src/Tools/t_shape/t_shape_dialog.ui +++ b/src/Tools/t_shape/t_shape_dialog.ui @@ -7,7 +7,7 @@ 0 0 349 - 283 + 524 @@ -98,15 +98,18 @@ + + + + Qt::Horizontal + + + QDialogButtonBox::Cancel|QDialogButtonBox::Ok + + + - - - - Build solid part - - - @@ -127,17 +130,102 @@ + + + + Build solid part + + + - - - Qt::Horizontal - - - QDialogButtonBox::Cancel|QDialogButtonBox::Ok - - + + + + + + + + Initial value + + + + + + + Get File Name + + + + + + + <html><head/><body><p><span style=" font-size:12pt; font-weight:600;">SalomePyQt testing</span></p></body></html> + + + + + + + 2 + + + Qt::Horizontal + + + + + + + Width main frame (px): + + + + + + + Initial value + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + Qt::Vertical + + + QSizePolicy::Fixed + + + + 20 + 40 + + + + + + + + Qt bindings package: + + + + + + + + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + +