--- a/Project/ProjectFormsBrowser.py Wed Nov 21 19:26:59 2018 +0100 +++ b/Project/ProjectFormsBrowser.py Sat Nov 24 15:37:04 2018 +0100 @@ -112,6 +112,10 @@ ] self.compileProc = None + self.__uicompiler = "" + + self.project.projectClosed.connect(self.__resetUiCompiler) + self.project.projectPropertiesChanged.connect(self.__resetUiCompiler) def _createPopupMenus(self): """ @@ -137,6 +141,10 @@ self.__generateDialogCode) self.menu.addSeparator() self.menu.addAction( + self.tr('Configure uic Compiler'), + self.__configureUicCompiler) + self.menu.addSeparator() + self.menu.addAction( self.tr('Open in Qt-Designer'), self.__openFile) self.menu.addAction( self.tr('Open in Editor'), self.__openFileInEditor) @@ -209,6 +217,10 @@ self.backMenu.addAction( self.tr('Compile all forms'), self.__compileAllForms) self.backMenu.addSeparator() + self.backMenu.addAction( + self.tr('Configure uic Compiler'), + self.__configureUicCompiler) + self.backMenu.addSeparator() self.backMenu.addAction(self.tr('New form...'), self.__newForm) else: if self.hooks["newForm"] is not None: @@ -232,10 +244,14 @@ self.multiMenu = QMenu(self) if self.project.getProjectType() in \ ["Qt4", "PyQt5", "E6Plugin", "PySide", "PySide2"]: - act = self.multiMenu.addAction( + self.multiMenu.addAction( self.tr('Compile forms'), self.__compileSelectedForms) self.multiMenu.addSeparator() self.multiMenu.addAction( + self.tr('Configure uic Compiler'), + self.__configureUicCompiler) + self.multiMenu.addSeparator() + self.multiMenu.addAction( self.tr('Open in Qt-Designer'), self.__openFile) self.multiMenu.addAction( self.tr('Open in Editor'), self.__openFileInEditor) @@ -277,6 +293,10 @@ self.dirMenu.addAction( self.tr('Compile all forms'), self.__compileAllForms) self.dirMenu.addSeparator() + self.dirMenu.addAction( + self.tr('Configure uic Compiler'), + self.__configureUicCompiler) + self.dirMenu.addSeparator() else: if self.hooks["compileAllForms"] is not None: self.dirMenu.addAction( @@ -322,6 +342,10 @@ self.dirMultiMenu.addAction( self.tr('Compile all forms'), self.__compileAllForms) self.dirMultiMenu.addSeparator() + self.dirMultiMenu.addAction( + self.tr('Configure uic Compiler'), + self.__configureUicCompiler) + self.dirMultiMenu.addSeparator() else: if self.hooks["compileAllForms"] is not None: self.dirMultiMenu.addAction( @@ -634,6 +658,58 @@ ## Methods to handle the various compile commands ########################################################################### + def __resetUiCompiler(self): + """ + Private slot to reset the determined UI compiler executable. + """ + self.__uicompiler = "" + + def __determineUiCompiler(self): + """ + Private method to determine the UI compiler for the project. + """ + self.__resetUiCompiler() + + if self.project.getProjectLanguage() in \ + ["Python", "Python2", "Python3"]: + if self.project.getProjectType() in ["Qt4", ]: + self.__uicompiler = Utilities.generatePyQtToolPath( + 'pyuic4', ["py3uic4", "py2uic4"]) + elif self.project.getProjectType() in ["PyQt5"]: + self.__uicompiler = Utilities.generatePyQtToolPath( + 'pyuic5', ["py3uic5", "py2uic5"]) + elif self.project.getProjectType() in ["E6Plugin"]: + if PYQT_VERSION < 0x050000: + self.__uicompiler = Utilities.generatePyQtToolPath( + 'pyuic4', ["py3uic4", "py2uic4"]) + else: + self.__uicompiler = Utilities.generatePyQtToolPath( + 'pyuic5', ["py3uic5", "py2uic5"]) + elif self.project.getProjectType() == "PySide": + self.__uicompiler = \ + Utilities.generatePySideToolPath('pyside-uic', "1") + elif self.project.getProjectType() == "PySide2": + self.__uicompiler = \ + Utilities.generatePySideToolPath('pyside2-uic', "2") + elif self.project.getProjectLanguage() == "Ruby": + if self.project.getProjectType() == "Qt4": + self.__uicompiler = 'rbuic4' + if Utilities.isWindowsPlatform(): + self.__uicompiler = \ + Utilities.getWindowsExecutablePath(self.__uicompiler) + + def getUiCompiler(self): + """ + Public method to get the UI compiler executable of the project. + + @return UI compiler executable + @rtype str + """ + if not self.__uicompiler: + self.__determineUiCompiler() + + return self.__uicompiler + def __readStdout(self): """ Private slot to handle the readyReadStandardOutput signal of the @@ -659,7 +735,7 @@ self.compileProc.setReadChannel(QProcess.StandardError) while self.compileProc and self.compileProc.canReadLine(): - s = self.uicompiler + ': ' + s = self.__uicompiler + ': ' error = str(self.compileProc.readLine(), ioEncoding, 'replace') s += error @@ -742,38 +818,8 @@ args = [] self.buf = "" - if self.project.getProjectLanguage() in \ - ["Python", "Python2", "Python3"]: - if self.project.getProjectType() in ["Qt4", ]: - self.uicompiler = Utilities.generatePyQtToolPath( - 'pyuic4', ["py3uic4", "py2uic4"]) - elif self.project.getProjectType() in ["PyQt5"]: - self.uicompiler = Utilities.generatePyQtToolPath( - 'pyuic5', ["py3uic5", "py2uic5"]) - elif self.project.getProjectType() in ["E6Plugin"]: - if PYQT_VERSION < 0x050000: - self.uicompiler = Utilities.generatePyQtToolPath( - 'pyuic4', ["py3uic4", "py2uic4"]) - else: - self.uicompiler = Utilities.generatePyQtToolPath( - 'pyuic5', ["py3uic5", "py2uic5"]) - elif self.project.getProjectType() == "PySide": - self.uicompiler = \ - Utilities.generatePySideToolPath('pyside-uic', "1") - elif self.project.getProjectType() == "PySide2": - self.uicompiler = \ - Utilities.generatePySideToolPath('pyside2-uic', "2") - else: - return None - elif self.project.getProjectLanguage() == "Ruby": - if self.project.getProjectType() == "Qt4": - self.uicompiler = 'rbuic4' - if Utilities.isWindowsPlatform(): - self.uicompiler = \ - Utilities.getWindowsExecutablePath(self.uicompiler) - else: - return None - else: + uicompiler = self.getUiCompiler() + if not uicompiler: return None ofn, ext = os.path.splitext(fn) @@ -787,8 +833,24 @@ indentWidth = Preferences.getQt("PyuicIndent") if indentWidth != self.PyuicIndentDefault: args.append("--indent={0}".format(indentWidth)) - if Preferences.getQt("PyuicFromImports"): - args.append("--from-imports") + + if self.project.getProjectType() in ["PySide", "PySide2"]: + # PySide and PySide2 + if Preferences.getQt("PyuicFromImports"): + args.append("--from-imports") + else: + # PyQt4 and PyQt5 + if 'uic5' in uicompiler and \ + PYQT_VERSION >= 0x050600 and \ + self.project.pdata["UICPARAMS"]["Package"]: + # only supported for PyQt5 >= 5.6 (April 2016) + args.append("--import-from={0}".format( + self.project.pdata["UICPARAMS"]["Package"])) + elif Preferences.getQt("PyuicFromImports"): + args.append("--from-imports") + if self.project.pdata["UICPARAMS"]["RcSuffix"]: + args.append("--resource-suffix={0}".format( + self.project.pdata["UICPARAMS"]["RcSuffix"])) elif self.project.getProjectLanguage() == "Ruby": self.compiledFile = ofn + '.rb' args.append('-x') @@ -799,7 +861,7 @@ self.compileProc.readyReadStandardError.connect(self.__readStderr) self.noDialog = noDialog - self.compileProc.start(self.uicompiler, args) + self.compileProc.start(uicompiler, args) procStarted = self.compileProc.waitForStarted(5000) if procStarted: self.compileRunning = True @@ -815,7 +877,7 @@ self.tr( 'Could not start {0}.<br>' 'Ensure that it is in the search path.' - ).format(self.uicompiler)) + ).format(uicompiler)) return None def __generateDialogCode(self): @@ -996,6 +1058,33 @@ Public slot used to handle the preferencesChanged signal. """ ProjectBaseBrowser.handlePreferencesChanged(self) + + self.__resetUiCompiler() + + def __configureUicCompiler(self): + """ + Private slot to configure some non-common uic compiler options. + """ + from .UicCompilerOptionsDialog import UicCompilerOptionsDialog + + params = self.project.pdata["UICPARAMS"] + + if self.project.getProjectType() in ["Qt4", "PyQt5", "E6Plugin"]: + dlg = UicCompilerOptionsDialog(params, self.getUiCompiler()) + if dlg.exec_() == QDialog.Accepted: + package, suffix = dlg.getData() + if package != params["Package"]: + params["Package"] = package + self.project.setDirty(True) + if suffix != params["RcSuffix"]: + params["RcSuffix"] = suffix + self.project.setDirty(True) + elif self.project.getProjectType() in ["PySide", "PySide2"]: + E5MessageBox.information( + self, + self.tr("Configure uic Compiler"), + self.tr("""No project specific uic compiler flags are""" + """ supported for PySide or PySide2.""")) ########################################################################### ## Support for hooks below