def getphase(self, **kwargs): """Return fluid phase kwarg: phase: direct msg Tc, Pc, T, P, x, region: to calculate by iapws""" data = { "Supercritical fluid": QApplication.translate( "pychemqt", "Supercritical fluid"), "Gas": QApplication.translate("pychemqt", "Gas"), "Compressible liquid": QApplication.translate( "pychemqt", "Compressible liquid"), "Critical point": QApplication.translate( "pychemqt", "Critical point"), "Saturated vapor": QApplication.translate( "pychemqt", "Saturated vapor"), "Saturated liquid": QApplication.translate( "pychemqt", "Saturated liquid"), "Two phases": QApplication.translate("pychemqt", "Two phases"), "Vapour": QApplication.translate("pychemqt", "Vapour"), "Liquid": QApplication.translate("pychemqt", "Liquid"), "Unknown": QApplication.translate("pychemqt", "Unknown")} if "phase" in kwargs: phase = kwargs["phase"] else: phase = getphase(**kwargs) return data[phase]
def isCalculable(self): """Check equipment input parameter Mandatory parameter: entrada, split Incompatibilities: salidas must be equal to len of split """ # Auto select split for trivial divider with one output stream if self.kwargs["salidas"] == 1: self.kwargs["split"] = [1.0] if not self.kwargs["entrada"]: self.msg = QApplication.translate("pychemqt", "undefined input") self.status = 0 elif not self.kwargs["split"]: self.msg = QApplication.translate("pychemqt", "undefined split fraction") self.status = 0 elif self.kwargs["salidas"] != len(self.kwargs["split"]): self.msg = QApplication.translate("pychemqt", "incomplete split fraction") self.status = 0 else: self.status = 1 self.msg = "" return True
def isCalculable(self): self.msg = "" self.status = 1 if not self.kwargs["comp"]: self.msg = QApplication.translate("pychemqt", "undefined components") self.status = 0 return if not self.kwargs["coef"]: self.msg = QApplication.translate("pychemqt", "undefined stequiometric") self.status = 0 return if self.kwargs["tipo"] == 0: if self.kwargs["conversion"] is None: self.msg = QApplication.translate("pychemqt", "undefined conversion") self.status = 3 elif self.kwargs["tipo"] == 1: if self.kwargs["keq"] is None: self.msg = QApplication.translate("pychemqt", "undefined equilibrium constants") self.status = 3 elif self.kwargs["tipo"] == 2: pass elif self.kwargs["tipo"] == 3: pass return True
def isCalculable(self): """Check equipment input parameter Mandatory parameter: entrada if valve is working, open or partially open Pout (DeltaP, Dew, Bubble) if valve is partially open """ if self.kwargs["off"] == 1: if not self.kwargs["entrada"]: self.msg = QApplication.translate("pychemqt", "undefined input") self.status = 0 elif self.kwargs["Pout"] or self.kwargs["DeltaP"] or self.kwargs["Dew"] or self.kwargs["Bubble"]: self.status = 1 self.msg = "" return True else: self.msg = QApplication.translate("pychemqt", "undefined exit condition") self.status = 0 elif self.kwargs["off"] == 2: self.msg = "" self.status = 1 return True else: if not self.kwargs["entrada"]: self.msg = QApplication.translate("pychemqt", "undefined input") self.status = 0 else: self.msg = "" self.status = 1 return True
def isCalculable(self): """Check equipment input parameter Mandatory parameter: entrada Pout if criterio is setted to 2 Incompatibilities: All corriente instance in entrada must be defined fine salidas must be equal to len of split Warnings: Some input stream have a warning status definitions """ if self.kwargs["criterio"] == 2 and not self.kwargs["Pout"]: self.msg = QApplication.translate("pychemqt", "pressure output not defined") self.status = 0 elif not self.kwargs["entrada"]: self.msg = QApplication.translate("pychemqt", "undefined input") self.status = 0 elif sum([s.status for s in self.kwargs["entrada"]]) == 0: self.msg = QApplication.translate("pychemqt", "undefined input") self.status = 0 elif len(self.kwargs["entrada"]) != sum([s.status for s in self.kwargs["entrada"]]): self.msg = QApplication.translate("pychemqt", "some input stream isn't defined") self.status = 3 return True else: self.msg = "" self.status = 1 return True
def propTxt(self): """Text format for report""" txt = "#---------------" txt += QApplication.translate("pychemqt", "Calculate properties") txt += "-----------------#" + os.linesep txt += self.propertiesToText(range(3)) txt += os.linesep txt += self.propertiesToText(3) for i, entrada in enumerate(self.kwargs["entrada"]): txt += ( "%-25s\t%s" % (QApplication.translate("pychemqt", "Input stream") + str(i), entrada.caudalmolar.str) + os.linesep ) txt += os.linesep txt += self.propertiesToText(4) for i, entrada in enumerate(self.kwargs["entrada"]): txt += ( "%-25s\t%s" % (QApplication.translate("pychemqt", "Input stream") + str(i), entrada.caudalmasico.str) + os.linesep ) txt += os.linesep txt += self.propertiesToText(5) for i, entrada in enumerate(self.kwargs["entrada"]): txt += ( "%-25s\t%s" % (QApplication.translate("pychemqt", "Input stream") + str(i), entrada.Q.str) + os.linesep ) txt += os.linesep + "#" txt += QApplication.translate("pychemqt", "Output Molar Composition") txt += os.linesep for comp, x in zip(self.salida[0].componente, self.salida[0].fraccion): txt += "%-25s\t %0.4f" % (comp.nombre, x) + os.linesep return txt
def propTxt(self): txt = "#---------------" txt += QApplication.translate("pychemqt", "Catalog") txt += "-----------------#" + os.linesep txt += self.propertiesToText(range(9)) if self.kwargs["accesorios"]: txt += os.linesep + "#---------------" txt += QApplication.translate("pychemqt", "Fittings") txt += "-----------------#"+os.linesep txt += self.propertiesToText(9) for accesorio in self.kwargs["accesorios"]: txt += "%5i %-22s\t %s" % (accesorio[3], accesorio[7], accesorio[2]) + os.linesep txt += os.linesep + "#---------------" txt += QApplication.translate("pychemqt", "Calculate properties") txt += "-----------------#" + os.linesep txt += self.propertiesToText(range(11, 24)) if self.kwargs["thermal"]: txt += self.propertiesToText(range(24, 26)) if self.statusCoste: txt += os.linesep+"#---------------" txt += QApplication.translate( "pychemqt", "Preliminary Cost Estimation") txt += "-----------------#" + os.linesep txt += self.propertiesToText(range(26, 31)) return txt
def propTxt(self): """Text format for report""" txt = "#---------------" txt += QApplication.translate("pychemqt", "Calculate properties") txt += "-----------------#" + os.linesep txt += self.propertiesToText(0) for i, salida in enumerate(self.salida): txt += ( "%-25s\t%s" % (QApplication.translate("pychemqt", "Output stream") + str(i), salida.caudalmolar.str) + os.linesep ) txt += os.linesep txt += self.propertiesToText(1) for i, salida in enumerate(self.salida): txt += ( "%-25s\t%s" % (QApplication.translate("pychemqt", "Output stream") + str(i), salida.caudalmasico.str) + os.linesep ) txt += os.linesep txt += self.propertiesToText(2) for i, salida in enumerate(self.salida): txt += ( "%-25s\t%s" % (QApplication.translate("pychemqt", "Output stream") + str(i), salida.Q.str) + os.linesep ) txt += os.linesep txt += self.propertiesToText(7) return txt
def addAction(self): # first show relevant information, if necessary if self.model.new: information = VariantHintDialog() information.exec() # TODO index = self.model.last if self.model.current > -1 else QModelIndex() last = self.model.current if self.model.current > -1 else Fence.TYPE length = self.model.length count = self.model.count dialog = VariantDataDialog(self.model.species, tax=self.tax, last=last, index=index, count=count, length=length) if dialog.exec() == QDialog.Accepted: values = dialog.value item = VariantItem(values[TreeModel.NameRole], values[TreeModel.ProtectionRole].TYPE) setattr(item, "color", values[TreeModel.ColorRole]) setattr(item, "plant", values[TreeModel.PlantRole]) setattr(item, "protection", values[TreeModel.ProtectionRole]) self.model.insertItem(item) # TODO self.model.count = dialog.count self.model.length = dialog.length # modify the create button if self.model.current == -1: buttonText = QApplication.translate("EnhancedTreeWidget", "Add protection type") # Schutz anlegen elif self.model.current == Fence.TYPE: buttonText = QApplication.translate("EnhancedTreeWidget", "Add Fence") # Zaun anlegen else: buttonText = QApplication.translate("EnhancedTreeWidget", "Add Tree Shelter") # Wuchshülle anlegen self.addButton.setText(buttonText)
def updatePlotLength(self): length = self.fenceLine.value() hint = False # update the chart, if necessary if length >= self.plotLength: self.paintCalculation() hint = True elif length < self.plotLength / 5: self.paintCalculation() hint = True if hint: # notice the user about the update notice = QMessageBox(self) notice.setWindowModality(Qt.WindowModal) # check for mac only notice.setIcon(QMessageBox.Information) notice.setStandardButtons(QMessageBox.Ok) notice.setWindowTitle(QApplication.translate("VariantPlotWidget", "Wuchshüllenrechner")) notice.setText("<b>" + QApplication.translate("VariantPlotWidget", "Die Skalierung wurde verändert!") + "</b>") notice.setInformativeText(QApplication.translate("VariantPlotWidget", "Da sich die Zaunlänge geändert hat, wurde die Skalierung " "des Diagramms ebenfalls verändert.")) notice.exec()
def contextMenuEvent(self, event): menu = QMenu() removeAction = menu.addAction(QA.translate('QOcrWidget', "Remove")) #Action = menu.addAction(self.scene().tr("Remove")) menu.addSeparator() textAction = menu.addAction(QA.translate('QOcrWidget', "Text")) graphicsAction = menu.addAction(QA.translate('QOcrWidget', "Graphics")) ## verification of the type of the selection and ## setting a check box near the type that is in use textAction.setCheckable(True) graphicsAction.setCheckable(True) if self.kind == 1: textAction.setChecked(True) elif self.kind == 2: graphicsAction.setChecked(True) selectedAction = menu.exec_(event.screenPos()) if selectedAction == removeAction: self.scene().removeArea(self) elif selectedAction == textAction: self.kind = 1 elif selectedAction == graphicsAction: self.kind = 2
def propertiesEquipment(cls): l = [(QApplication.translate("pychemqt", "Mode"), ("TEXT_TIPO", "tipo_calculo"), str), (QApplication.translate("pychemqt", "Model"), ("TEXT_MODEL", "modelo_rendimiento"), str), (QApplication.translate("pychemqt", "Pressure Loss Model"), ("TEXT_MODEL_DELTAP", "modelo_DeltaP"), str), (QApplication.translate("pychemqt", "Throat Diameter"), "Dt", Length), (QApplication.translate("pychemqt", "Throat Length"), "Lt", Length), (QApplication.translate( "pychemqt", "Johnstone method scrubber constant"), "k", Dimensionless), (QApplication.translate( "pychemqt", "Calvert method scrubber constant"), "f", Dimensionless), (QApplication.translate("pychemqt", "Drops Diameter"), "dd", Length), (QApplication.translate("pychemqt", "Throat Cross Area"), "At", Area), (QApplication.translate("pychemqt", "Throat Speed"), "Vg", Speed)] for prop in Separador_SolidGas.propertiesEquipment(): l.append(prop) return l
def checkSaveState(self): if self.model.changed: question = QMessageBox(self) question.setWindowModality(Qt.WindowModal) # check for mac only question.setIcon(QMessageBox.Warning) question.setStandardButtons(QMessageBox.Save|QMessageBox.Discard|QMessageBox.Cancel) question.setDefaultButton(QMessageBox.Save) question.setWindowTitle(QApplication.translate("MainWindow", "Wuchshüllenrechner")) question.setText("<b>" + QApplication.translate("MainWindow", "Do you want to save the changes you made<br>" "to the current calculation?") + "</b>") question.setInformativeText(QApplication.translate("MainWindow", "Your changes will be lost if you don't save them.")) reply = question.exec() if reply == QMessageBox.Save: if self.saveAction(): #self.model.clear() self.clear() return True else: return False elif reply == QMessageBox.Discard: #self.model.clear() self.clear() return True else: return False # always clear self.clear() return True
def main(): global app # register representation factories baseRepresentationFactories.registerAllFactories() representationFactories.registerAllFactories() # initialize the app app = Application(sys.argv) app.setOrganizationName("TruFont") app.setOrganizationDomain("trufont.github.io") app.setApplicationName("TruFont") app.setApplicationVersion(__version__) app.setWindowIcon(QIcon(":app.png")) app.setAttribute(Qt.AA_UseHighDpiPixmaps, True) # Install stream redirection app.outputWindow = OutputWindow() # Exception handling sys.excepthook = exceptionCallback # Qt's translation for itself. May not be installed. qtTranslator = QTranslator() qtTranslator.load("qt_" + QLocale.system().name(), QLibraryInfo.location(QLibraryInfo.TranslationsPath)) app.installTranslator(qtTranslator) appTranslator = QTranslator() appTranslator.load("trufont_" + QLocale.system().name(), os.path.dirname(os.path.realpath(__file__)) + "/resources") app.installTranslator(appTranslator) # parse options and open fonts parser = QCommandLineParser() parser.setApplicationDescription(QApplication.translate( "Command-line parser", "The TruFont font editor.")) parser.addHelpOption() parser.addVersionOption() parser.addPositionalArgument(QApplication.translate( "Command-line parser", "files"), QApplication.translate( "Command-line parser", "The UFO files to open.")) parser.process(app) args = parser.positionalArguments() if not args: fontPath = None # maybe load recent file settings = QSettings() loadRecentFile = settings.value("misc/loadRecentFile", False, bool) if loadRecentFile: recentFiles = settings.value("core/recentFiles", [], type=str) if len(recentFiles) and os.path.exists(recentFiles[0]): fontPath = recentFiles[0] app.openFile(fontPath) # otherwise, create a new file if fontPath is None: app.newFile() else: for fontPath in args: app.openFile(fontPath) sys.exit(app.exec_())
def propertiesEquipment(cls): """Properties availables to show in report""" l = [ (QApplication.translate("pychemqt", "Output Temperature"), "outT", unidades.Temperature), (QApplication.translate("pychemqt", "Output Pressure"), "Pout", unidades.Pressure), (QApplication.translate("pychemqt", "Output vapor fraction"), "outX", unidades.Dimensionless), (QApplication.translate("pychemqt", "Working Condition"), ("TEXT_WORKING", "off"), str), ] return l
def retranslateUi(self): # translate the buttons self.addButton.setText(QApplication.translate("EnhancedTreeWidget", "Add protection type")) # Schutz anlegen self.removeButton.setText(QApplication.translate("EnhancedTreeWidget", "Remove protection type")) # Schutz Entfernen self.modifyButton.setText(QApplication.translate("EnhancedTreeWidget", "Modify Protection type")) # Schutz Ändern self.calcButton.setText(QApplication.translate("EnhancedTreeWidget", "Calculate")) # Berechnen # translate the view self.view.update()
def properties(cls): prop = Thermo.properties()[:] l = [ (QApplication.translate("pychemqt", "Dielectric constant"), "epsilon", unidades.Dimensionless), (QApplication.translate("pychemqt", "Refractive index"), "n", unidades.Dimensionless), ] for p in l: prop.insert(-11, p) return prop
def __evt_category_contextMenu(self, p): """ yeahdoc class context menu """ item = self.yeahdoccategorylist.currentItem() if item and item.getMark(): menu = QMenu() action = QAction(QIcon(getPath("iconDir", "yeahdoc/item.png")), item.text(), self) action.setIconVisibleInMenu(True) menu.addAction(action) menu.addSeparator() action = QAction(QIcon(getPath("iconDir", "yeahdoc/open.png")), QApplication.translate("YeahdocList", "Open"), self, \ triggered=lambda re, id=item.getMark(): self.__setupyeahdoclisttreeDatas(id)) action.setIconVisibleInMenu(True) menu.addAction(action) action = QAction(QIcon(getPath("iconDir", "yeahdoc/refresh.png")), QApplication.translate("YeahdocList", "Refresh"), self, \ triggered=self.refreshClasslist) action.setIconVisibleInMenu(True) menu.addAction(action) menu.addSeparator() # merge class merge_class_menu = QMenu() current_categoryid = item.getMark() for class_item in YeahdocDatasSupply().bc_list(): if not str(class_item['id']) == current_categoryid: action = QAction(class_item["title"], self, \ triggered=lambda re, item=item, categoryid=str(class_item["id"]): \ YeahdocDatasSupply().bc_merge(current_categoryid, categoryid)) action.setIcon(QIcon(getPath("iconDir", "yeahdoc/flag/%s" % str(class_item["img"])))) action.setIconVisibleInMenu(True) merge_class_menu.addAction(action) action = QAction(QIcon(getPath("iconDir", "yeahdoc/merge.png")), QApplication.translate("YeahdocList", "Merge"), self) action.setIconVisibleInMenu(True) action.setMenu(merge_class_menu) menu.addAction(action) menu.addAction(self.__actions["__yeahdoc_c_cleardatas__"]) menu.addSeparator() menu.addAction(self.__actions["__yeahdoc_c_new__"]) menu.addAction(self.__actions["__yeahdoc_c_edit__"]) menu.addAction(self.__actions["__yeahdoc_c_rename__"]) menu.addAction(self.__actions["__yeahdoc_c_delete__"]) menu.exec_(self.mapToGlobal(self.yeahdoccategorylist.mapTo(self, p)))
def data(self, index, role=Qt.DisplayRole): if not index.isValid(): return None item = index.internalPointer() column = index.column() if role == Qt.DisplayRole: if column == TreeModel.TYPE: return QApplication.translate("VariantItem", item.protection.TYPE_DESCRIPTION) elif column == TreeModel.NAME: return item.name elif column == TreeModel.SPECIES: return library.TREESPECIES_ABBREVIATION[item.plant.species] elif column == TreeModel.IDENTIFICATION: return "{protection}{identification}".format( protection=QApplication.translate("VariantItem", item.protection.TYPE_SHORT), identification=item.identification + 1) elif role == Qt.CheckStateRole: if column == TreeModel.TYPE: if item.status: if item.type == Fence.TYPE: checked = True for child in item.children: if not child.status: checked = False if checked: return Qt.Checked else: return Qt.PartiallyChecked else: return Qt.Checked else: return Qt.Unchecked elif role == self.IdentificationRole: return "{protection}{identification}".format( protection=QApplication.translate("VariantItem", item.protection.TYPE_SHORT), identification=item.identification + 1) elif role == self.LengthRole: return self.project.length elif role == self.CountRole: return self.project.count elif role == self.TypeRole: return item.type elif role == self.NameRole: return item.name elif role == self.SpeciesRole: return item.plant.species elif role == self.ColorRole: return QColor(item.color) elif role == self.StatusRole: return item.status elif role == self.ResultRole: return item.result else: return None
def retranslateUi(self): # input fields self.viewLabel.setText(QApplication.translate("PlotControlWidget", "Chart view") + ":") # Diagrammansicht self.viewInput.clear() for item in self._COMBOBOX_ITEM_LIST: self.viewInput.addItem(QApplication.translate("PlotControlWidget", item)) self.lengthCheckBox.setText(QApplication.translate("PlotControlWidget", "Fence length") + ":") # Zaunlänge self.countCheckBox.setText(QApplication.translate("PlotControlWidget", "Number of plants") + ":") # Anzahl der Pflanzen self.countCalculator.setText(QApplication.translate("PlotControlWidget", "Calculation help")) # Umrechnungshilfe
def unload(self): self.iface.removePluginMenu( "&"+QApplication.translate("nominatim", "OSM place search", None) + "...", self.act_config) self.iface.removePluginMenu( "&"+QApplication.translate("nominatim", "OSM place search", None) + "...", self.act_nominatim_help) self.store() self.deactivate() self.iface.removeDockWidget(self.nominatim_dlg)
def exportAction(self): dialog = QFileDialog(self) dialog.setWindowModality(Qt.WindowModal) # check for mac only dialog.setAcceptMode(QFileDialog.AcceptSave) dialog.setWindowTitle(QApplication.translate("MainWindow", "Export Calculation")) dialog.setDirectory(os.path.expanduser("~")) dialog.setNameFilter(QApplication.translate("MainWindow", "PNG files (*.png);;JPG files (*.jpg);;TIFF files (*.tif)")) if dialog.exec(): filename = dialog.selectedFiles() self.plotWidget.plotWidget.plotWidget.export(filename.pop())
def propTxt(self): txt = "#---------------" txt += QApplication.translate("pychemqt", "Data map") txt += "-----------------#" + os.linesep txt += self.propertiesToText(0) if self.kwargs["datamap"]: for data in self.kwargs["datamap"]: txt += "{0[entity]}.{0[property]}.{0[unit]} ---> {0[sheet]}.{0[cell]}".format(data)+os.linesep else: txt += QApplication.translate("pychemqt", "Undefined")+os.linesep return txt
def retranslateUi(self): # dialog titel self.setWindowTitle(QApplication.translate("ScientificBasisDialog", "Specialist articles")) # Wissenschaftliche Grundlage # headline and description self.headline.setText(QApplication.translate("ScientificBasisDialog", "Specialist articles")) # Wissenschaftliche Beiträge self.description.setText(QApplication.translate("ScientificBasisDialog", "Hier finden Sie grundlegende Fachbeiträge zur Thematik") + ":") # buttons self.openButton.setText(QApplication.translate("ScientificBasisDialog", "Open article")) # Beitrag öffnen self.closeButton.setText(QApplication.translate("ScientificBasisDialog", "Close")) # Schließen
def fillNone(self, fase): """Fill properties in null phase with a explicative msg""" fase._bool = False if self.x == 0: txt = QApplication.translate("pychemqt", "Subcooled") elif self.Tr < 1 and self.Pr < 1: txt = QApplication.translate("pychemqt", "Superheated") elif self.Tr == 1 and self.Pr == 1: txt = QApplication.translate("pychemqt", "Critic point") else: txt = QApplication.translate("pychemqt", "Supercritical") for key in self.propertiesPhase(): fase.__setattr__(key, txt)
def propTxt(self): txt = "#---------------" txt += QApplication.translate("pychemqt", "Calculate properties") txt += "-----------------#"+os.linesep txt += self.propertiesToText(range(11)) if self.statusCoste: txt += os.linesep+"#---------------" txt += QApplication.translate( "pychemqt", "Preliminary Cost Estimation") txt += "-----------------#" + os.linesep txt += self.propertiesToText(range(11, 16)) return txt
def isCalculable(self): self.msg = "" self.status = 1 if not self.kwargs["filename"] or \ not os.path.isfile(self.kwargs["filename"]): self.msg = QApplication.translate( "pychemqt", "undefined spreadsheet filename") self.status = 0 return if not self.kwargs["datamap"]: self.msg = QApplication.translate( "pychemqt", "undefined spreadsheet data map") self.status = 3 return True
def getphase(self, fld): """Return fluid phase Override refprop original function with translation support""" # check if fld above critical pressure if fld['p'] > self.Pc.kPa: # check if fld above critical pressure if fld['t'] > self.Tc: return QApplication.translate("pychemqt", "Supercritical fluid"), 1. else: return QApplication.translate("pychemqt", "Compressible liquid"), 1. # check if fld above critical pressure elif fld['t'] > self.Tc: return QApplication.translate("pychemqt", "Gas"), 1. # check if ['q'] in fld if 'q' not in list(fld.keys()): if 'h' in list(fld.keys()): fld['q'] = refprop.flsh('ph', fld['p'], fld['h'], fld['x'])['q'] elif 's' in list(fld.keys()): fld['q'] = refprop.flsh('ps', fld['p'], fld['s'], fld['x'])['q'] # check q if fld['q'] > 1: return QApplication.translate("pychemqt", "Vapor"), 1. elif fld['q'] == 1: return QApplication.translate("pychemqt", "Saturated vapor"), 1. elif 0 < fld['q'] < 1: return QApplication.translate("pychemqt", "Two phases"), fld['q'] elif fld['q'] == 0: return QApplication.translate("pychemqt", "Saturated liquid"), 0. elif fld['q'] < 0: return QApplication.translate("pychemqt", "Liquid"), 0.
def openAction(self): # first check save state of the current calculation if self.checkSaveState(): dialog = QFileDialog(self) dialog.setWindowModality(Qt.WindowModal) # check for mac only dialog.setWindowTitle(QApplication.translate("MainWindow", "Open Calculation")) dialog.setDirectory(os.path.expanduser("~")) dialog.setNameFilter(QApplication.translate("MainWindow", "XML files (*.xml);;All Files (*)")) dialog.exec() filename = dialog.selectedFiles() if filename: self.model.readFile(filename.pop())
def drawFontVerticalMetrics(painter, glyph, scale, rect, drawLines=True, drawText=True, color=None): font = glyph.font if font is None: return if color is None: color = defaultColor("fontVerticalMetrics") painter.save() painter.setPen(color) # gather y positions toDraw = [ (QApplication.translate("drawing", "Descender"), font.info.descender), (QApplication.translate("drawing", "Baseline"), 0), (QApplication.translate("drawing", "x-height"), font.info.xHeight), (QApplication.translate("drawing", "Cap height"), font.info.capHeight), (QApplication.translate("drawing", "Ascender"), font.info.ascender), ] positions = {} for name, position in toDraw: if position is None: continue if position not in positions: positions[position] = [] positions[position].append(name) # create lines xMin = rect[0] xMax = xMin + rect[2] lines = [] for y, names in positions.items(): names = ", ".join(names) if y != 0: names = "%s (%d)" % (names, y) lines.append((y, names)) # draw lines if drawLines: lineWidth = 1.0 * scale for y, names in lines: drawLine(painter, xMin, y, xMax, y, lineWidth=lineWidth) # draw text if drawText: fontSize = 9 x = glyph.width + 6 * scale for y, text in lines: y -= (fontSize / 3.5) * scale drawTextAtPoint(painter, text, x, y, scale) painter.restore()
def main(): global app # register representation factories baseRepresentationFactories.registerAllFactories() representationFactories.registerAllFactories() if hasattr(Qt, "AA_EnableHighDpiScaling"): QApplication.setAttribute(Qt.AA_EnableHighDpiScaling) platformSpecific.setAppName() # initialize the app app = Application(sys.argv) app.setOrganizationName("TruFont") app.setOrganizationDomain("trufont.github.io") app.setApplicationName("TruFont") app.setApplicationVersion(__version__) app.setWindowIcon(QIcon(":app.png")) app.setAttribute(Qt.AA_UseHighDpiPixmaps, True) appFont = platformSpecific.UIFontOverride() if appFont is not None: app.setFont(appFont) app.setStyleSheet(platformSpecific.appStyleSheet()) # Install stream redirection app.outputWindow = OutputWindow() # Exception handling sys.excepthook = errorReports.exceptionCallback # Qt's translation for itself. May not be installed. qtTranslator = QTranslator() qtTranslator.load( "qt_" + QLocale.system().name(), QLibraryInfo.location(QLibraryInfo.TranslationsPath), ) app.installTranslator(qtTranslator) appTranslator = QTranslator() appTranslator.load( "trufont_" + QLocale.system().name(), os.path.dirname(os.path.realpath(__file__)) + "/resources", ) app.installTranslator(appTranslator) # parse options and open fonts parser = QCommandLineParser() parser.setApplicationDescription( QApplication.translate("Command-line parser", "The TruFont font editor.") ) parser.addHelpOption() parser.addVersionOption() parser.addPositionalArgument( QApplication.translate("Command-line parser", "files"), QApplication.translate("Command-line parser", "The UFO files to open."), ) parser.process(app) # load menu if platformSpecific.useGlobalMenuBar(): app.fetchMenuBar() app.setQuitOnLastWindowClosed(False) # bootstrap extensions folder = app.getExtensionsDirectory() for file in os.listdir(folder): if not file.rstrip("\\/ ").endswith(".tfExt"): continue path = os.path.join(folder, file) try: extension = TExtension(path) if extension.launchAtStartup: extension.run() except Exception as e: msg = QApplication.translate( "Extensions", f"The extension at {path} could not be run." ) errorReports.showWarningException(e, msg) continue app.registerExtension(extension) # process files args = parser.positionalArguments() if not args: # maybe load recent file loadRecentFile = settings.loadRecentFile() if loadRecentFile: recentFiles = settings.recentFiles() if len(recentFiles) and os.path.exists(recentFiles[0]): app.openFile(recentFiles[0]) else: for fontPath in args: app.openFile(fontPath) # if we did not open a font, spawn new font or go headless if not app.allFonts(): if platformSpecific.shouldSpawnDocument(): app.newFile() else: # HACK: on OSX we may want to trigger native QMenuBar display # without opening any window. Since Qt infers new menu bar on # focus change, fire the signal. app.focusWindowChanged.emit(None) sys.exit(app.exec_())
def extractProfileIkawaCSV(file): res = {} # the interpreted data set res["samplinginterval"] = 1.0 # set profile date from the file name if it has the format "IKAWA yyyy-mm-dd hhmmss.csv" filename = os.path.basename(file) p = re.compile('IKAWA \d{4,4}-\d{2,2}-\d{2,2} \d{6,6}.csv') if p.match(filename): s = filename[6:-4] # the extracted date time string date = QDateTime.fromString(s,"yyyy-MM-dd HHmmss") res["roastdate"] = encodeLocal(date.date().toString()) res["roastisodate"] = encodeLocal(date.date().toString(Qt.ISODate)) res["roasttime"] = encodeLocal(date.time().toString()) res["roastepoch"] = int(date.toTime_t()) res["roasttzoffset"] = libtime.timezone csvFile = io.open(file, 'r', newline="",encoding='utf-8') data = csv.reader(csvFile,delimiter=',') #read file header header = next(data) fan = None # holds last processed fan event value fan_last = None # holds the fan event value before the last one heater = None # holds last processed heater event value heater_last = None # holds the heater event value before the last one fan_event = False # set to True if a fan event exists heater_event = False # set to True if a heater event exists specialevents = [] specialeventstype = [] specialeventsvalue = [] specialeventsStrings = [] timex = [] temp1 = [] temp2 = [] extra1 = [] extra2 = [] timeindex = [-1,0,0,0,0,0,0,0] #CHARGE index init set to -1 as 0 could be an actal index used i = 0 for row in data: i = i + 1 items = list(zip(header, row)) item = {} for (name, value) in items: item[name] = value.strip() # take i as time in seconds timex.append(i) # we map IKAWA Exhaust to BT as main events like CHARGE and DROP are marked on BT in Artisan temp1.append(-1) if 'exaust temp' in item: temp2.append(float(item['exaust temp'])) else: temp2.append(-1) # mark CHARGE if not timeindex[0] > -1 and 'state' in item and item['state'] == 'doser open': timeindex[0] = i # mark DROP if timeindex[6] == 0 and 'state' in item and item['state'] == 'cooling': timeindex[6] = i # add SET and RPM if 'temp set' in item: extra1.append(float(item['temp set'])) else: extra1.append(-1) if 'fan speed (RPM)' in item: rpm = float(item['fan speed (RPM)']) extra2.append(rpm/100) else: extra2.append(-1) if "fan set (%)" in item: try: v = float(item["fan set (%)"]) if v != fan: # fan value changed if v == fan_last: # just a fluctuation, we remove the last added fan value again fan_last_idx = next(i for i in reversed(range(len(specialeventstype))) if specialeventstype[i] == 0) del specialeventsvalue[fan_last_idx] del specialevents[fan_last_idx] del specialeventstype[fan_last_idx] del specialeventsStrings[fan_last_idx] fan = fan_last fan_last = None else: fan_last = fan fan = v fan_event = True v = v/10. + 1 specialeventsvalue.append(v) specialevents.append(i) specialeventstype.append(0) specialeventsStrings.append(item["fan set (%)"] + "%") else: fan_last = None except Exception as e: pass if "heater power (%)" in item: try: v = float(item["heater power (%)"]) if v != heater: # heater value changed if v == heater_last: # just a fluctuation, we remove the last added heater value again heater_last_idx = next(i for i in reversed(range(len(specialeventstype))) if specialeventstype[i] == 3) del specialeventsvalue[heater_last_idx] del specialevents[heater_last_idx] del specialeventstype[heater_last_idx] del specialeventsStrings[heater_last_idx] heater = heater_last heaster_last = None else: heater_last = heater heater = v heater_event = True v = v/10. + 1 specialeventsvalue.append(v) specialevents.append(i) specialeventstype.append(3) specialeventsStrings.append(item["heater power (%)"] + "%") else: heater_last = None except: pass csvFile.close() res["timex"] = timex res["temp1"] = temp1 res["temp2"] = temp2 res["timeindex"] = timeindex res["extradevices"] = [25] res["extratimex"] = [timex] res["extraname1"] = ["SET"] res["extratemp1"] = [extra1] res["extramathexpression1"] = [""] res["extraname2"] = ["RPM"] res["extratemp2"] = [extra2] res["extramathexpression2"] = ["x/100"] if len(specialevents) > 0: res["specialevents"] = specialevents res["specialeventstype"] = specialeventstype res["specialeventsvalue"] = specialeventsvalue res["specialeventsStrings"] = specialeventsStrings if heater_event or fan_event: # first set etypes to defaults res["etypes"] = [QApplication.translate("ComboBox", "Air",None), QApplication.translate("ComboBox", "Drum",None), QApplication.translate("ComboBox", "Damper",None), QApplication.translate("ComboBox", "Burner",None), "--"] # update if fan_event: res["etypes"][0] = "Fan" if heater_event: res["etypes"][3] = "Heater" return res
class PenTool(BaseTool): icon = _path name = QApplication.translate("PenTool", "Pen") shortcut = "P" def __init__(self, parent=None): super().__init__(parent) self._shouldMoveOnCurve = False self._stashedOffCurve = None self._targetContour = None def toolActivated(self): glyph = self._glyph glyph.addObserver(self, "_selectionChanged", "Glyph.SelectionChanged") def toolDisabled(self): glyph = self._glyph glyph.removeObserver(self, "Glyph.SelectionChanged") self._cleanupTrailingOffcurve() assert not self._shouldMoveOnCurve # notifications def _selectionChanged(self, notification): if len(self._glyph.selection) != 1: self._cleanupTrailingOffcurve() # helpers def _cleanupTrailingOffcurve(self): for contour in self._glyph: if not (contour and contour.open): continue point = contour[-1] if point.segmentType is None: # TODO(meta): should we emit selection changed if deleted point # was selected? contour.removePoint(point) contour[-1].smooth = False def _getSelectedCandidatePoint(self): """ If there is exactly one point selected in the glyph at the edge of an open contour, return said contour. Else return None. """ candidates = set() shouldReverse = False for contour in self._glyph: # we're after an open contour... if not (len(contour) and contour.open): continue # ...with the last point selected sel = contour.selection if not len(sel) == 1: continue lastPoint = contour[-1] if not lastPoint.selected: if not contour[0].selected: continue shouldReverse = True else: shouldReverse = False candidates.add(contour) if len(candidates) == 1: ret = next(iter(candidates)) if shouldReverse: ret.reverse() return ret return None def _coerceSegmentToCurve(self, contour, pt, pos): contour.holdNotifications() index = contour.index(pt) or len(contour) otherPt = contour.getPoint(index - 1) # add an offCurve before pt if contour.open: # inverse point secondX = 2 * pt.x - pos.x() secondY = 2 * pt.y - pos.y() smooth = True else: # closed contour we pull the point with the mouse secondX = pos.x() secondY = pos.y() smooth = False contour.insertPoint(index, pt.__class__((secondX, secondY))) # add the first of two offCurves if self._stashedOffCurve is not None: offCurve, onSmooth = self._stashedOffCurve otherPt.smooth = index - 1 and onSmooth contour.insertPoint(index, offCurve) self._stashedOffCurve = None else: firstX = otherPt.x + round(.35 * (pt.x - otherPt.x)) firstY = otherPt.y + round(.35 * (pt.y - otherPt.y)) contour.insertPoint(index, pt.__class__((firstX, firstY))) # now flag pt as curve point pt.segmentType = "curve" pt.smooth = smooth contour.releaseHeldNotifications() def _updateOnCurveSmoothness(self, event): contour = self._targetContour if contour is not None: if len(contour) < 2: return pt = contour[-1] if pt.selected: # grab the onCurve. if not the previous point, it's the one # before it if pt.segmentType is None: pt = contour[-2] # this shouldn't happen, but guard whatsoever if pt.segmentType is None: return if pt == contour[0]: return pt.smooth = not event.modifiers() & Qt.AltModifier contour.dirty = True # events def keyPressEvent(self, event): self._updateOnCurveSmoothness(event) self._shouldMoveOnCurve = event.key() == Qt.Key_Space def keyReleaseEvent(self, event): self._updateOnCurveSmoothness(event) if event.key() == Qt.Key_Space: self._shouldMoveOnCurve = False def mousePressEvent(self, event): if event.button() != Qt.LeftButton: super().mousePressEvent(event) return self._glyph.beginUndoGroup() self._origin = event.localPos() widget = self.parent() candidate = self._getSelectedCandidatePoint() mouseItem = widget.itemAt(self._origin) # if we clicked on an item, see if we should join the current contour if isinstance(mouseItem, tuple): contour, index = mouseItem if contour == candidate and not index: point = contour[index] lastPoint = candidate[-1] lastPoint.selected = False if lastPoint.segmentType is not None: point.segmentType = "line" else: contour.removePoint(lastPoint) self._stashedOffCurve = (lastPoint, contour[-1].smooth) contour[-1].smooth = False point.segmentType = "line" point.selected = True point.smooth = False candidate.postNotification( notification="Contour.SelectionChanged") candidate.dirty = True self._targetContour = candidate return canvasPos = event.pos() x, y = canvasPos.x(), canvasPos.y() # otherwise, add a point to current contour if applicable if candidate is not None: contour = candidate lastPoint = contour[-1] lastPoint.selected = False if event.modifiers() & Qt.ShiftModifier: pos = self.clampToOrigin( self._origin, QPointF(lastPoint.x, lastPoint.y)).toPoint() x, y = pos.x(), pos.y() if not lastPoint.segmentType: contour.removePoint(lastPoint) self._stashedOffCurve = (lastPoint, contour[-1].smooth) contour[-1].smooth = False pointType = "line" # or create a new one else: contour = self._glyph.instantiateContour() self._glyph.appendContour(contour) pointType = "move" # in any case here, unselect all points (*click*) and enable new point self._glyph.selected = False contour.addPoint((x, y), pointType) contour[-1].selected = True contour.postNotification( notification="Contour.SelectionChanged") self._targetContour = contour def mouseMoveEvent(self, event): if not event.buttons() & Qt.LeftButton: super().mouseMoveEvent(event) return contour = self._targetContour if contour is None: return # we don't make any check here, mousePressEvent did it for us pos = event.pos() # selected point pt = contour[-1] if not contour.open: pt_ = contour[0] if pt_.selected: pt = pt_ if pt.segmentType and not self._shouldMoveOnCurve: # don't make a curve until enough distance is reached widget = self.parent() rect = QRectF(self._origin, event.localPos()) widgetRect = widget.mapRectFromCanvas(rect) if (widgetRect.bottomRight() - widgetRect.topLeft( )).manhattanLength() < 10: return # go onSmooth = not event.modifiers() & Qt.AltModifier pt.selected = False pt.smooth = len(contour) > 1 and onSmooth contour.holdNotifications() if pt.segmentType == "line" and onSmooth: self._coerceSegmentToCurve(contour, pt, pos) elif pt.smooth and contour.open: # if there's a curve segment behind, we need to update the # offCurve's position to inverse if len(contour) > 1: onCurveBefore = contour[-2] onCurveBefore.x = 2 * pt.x - pos.x() onCurveBefore.y = 2 * pt.y - pos.y() if contour.open: contour.addPoint((pos.x(), pos.y())) contour[-1].selected = True contour.postNotification( notification="Contour.SelectionChanged") contour.releaseHeldNotifications() else: if pt.segmentType: onCurve = pt elif contour.open: onCurve = contour[-2] else: onCurve = contour[0] if event.modifiers() & Qt.ShiftModifier: pos = self.clampToOrigin( event.localPos(), QPointF(onCurve.x, onCurve.y)).toPoint() if self._shouldMoveOnCurve: dx = pos.x() - pt.x dy = pos.y() - pt.y moveUIPoint(contour, onCurve, (dx, dy)) else: pt.x = pos.x() pt.y = pos.y() if contour.open and len(contour) >= 3 and onCurve.smooth: if onCurve.segmentType == "line": self._coerceSegmentToCurve(contour, onCurve, pos) otherSidePoint = contour[-3] otherSidePoint.x = 2 * onCurve.x - pos.x() otherSidePoint.y = 2 * onCurve.y - pos.y() contour.dirty = True def mouseReleaseEvent(self, event): if event.button() == Qt.LeftButton: self._shouldMoveOnCurve = False self._stashedOffCurve = None self._targetContour = None self._glyph.endUndoGroup() else: super().mouseReleaseEvent(event)
def content(): strlist = [] helpstr = '' #@UnusedVariable newline = '\n' #@UnusedVariable strlist.append('<head><style> td, th {border: 1px solid #ddd; padding: 6px;} th {padding-top: 6px;padding-bottom: 6px;text-align: left;background-color: #0C6AA6; color: white;} </style></head> <body>') strlist.append("<b>") strlist.append(QApplication.translate('HelpDlg','SYMBOLIC VARIABLES',None)) strlist.append("</b>") tbl_SymbolicVariables = prettytable.PrettyTable() tbl_SymbolicVariables.field_names = [QApplication.translate('HelpDlg','Symbol',None),QApplication.translate('HelpDlg','Description',None),QApplication.translate('HelpDlg','Can shift?\n(see below)',None)] tbl_SymbolicVariables.add_row(['t',QApplication.translate('HelpDlg','Absolute time (seconds) from begin of recording (not only the time after CHARGE!)',None),QApplication.translate('HelpDlg','Yes',None)]) tbl_SymbolicVariables.add_row(['b',QApplication.translate('HelpDlg','Absolute time (seconds) from begin of recording of the background profile',None),QApplication.translate('HelpDlg','Yes',None)]) tbl_SymbolicVariables.add_row(['x',QApplication.translate('HelpDlg','Current channel reading (not available in the Plotter)',None),' ']) tbl_SymbolicVariables.add_row(['Y1',QApplication.translate('HelpDlg','ET value',None),QApplication.translate('HelpDlg','Yes',None)]) tbl_SymbolicVariables.add_row(['Y2',QApplication.translate('HelpDlg','BT value',None),QApplication.translate('HelpDlg','Yes',None)]) tbl_SymbolicVariables.add_row(['Y3',QApplication.translate('HelpDlg','Extra #1 T1 value',None),QApplication.translate('HelpDlg','Yes',None)]) tbl_SymbolicVariables.add_row(['Y4',QApplication.translate('HelpDlg','Extra #1 T2 value',None),QApplication.translate('HelpDlg','Yes',None)]) tbl_SymbolicVariables.add_row(['Y5',QApplication.translate('HelpDlg','Extra #2 T1 value',None),QApplication.translate('HelpDlg','Yes',None)]) tbl_SymbolicVariables.add_row(['Y6',QApplication.translate('HelpDlg','Extra #2 T2 value',None),QApplication.translate('HelpDlg','Yes',None)]) tbl_SymbolicVariables.add_row(['...',QApplication.translate('HelpDlg','...and so forth',None),QApplication.translate('HelpDlg','Yes',None)]) tbl_SymbolicVariables.add_row(['B1',QApplication.translate('HelpDlg','ET background',None),QApplication.translate('HelpDlg','Yes',None)]) tbl_SymbolicVariables.add_row(['B2',QApplication.translate('HelpDlg','BT background',None),QApplication.translate('HelpDlg','Yes',None)]) tbl_SymbolicVariables.add_row(['B3',QApplication.translate('HelpDlg','ExtraBackground #1-A',None),QApplication.translate('HelpDlg','Yes',None)]) tbl_SymbolicVariables.add_row(['B4',QApplication.translate('HelpDlg','ExtraBackground #1-B',None),QApplication.translate('HelpDlg','Yes',None)]) tbl_SymbolicVariables.add_row(['B5',QApplication.translate('HelpDlg','ExtraBackground #2-A',None),QApplication.translate('HelpDlg','Yes',None)]) tbl_SymbolicVariables.add_row(['...',QApplication.translate('HelpDlg','...and so forth',None),QApplication.translate('HelpDlg','Yes',None)]) tbl_SymbolicVariables.add_row(['T1',QApplication.translate('HelpDlg','ET tare value',None),' ']) tbl_SymbolicVariables.add_row(['T2',QApplication.translate('HelpDlg','BT tare value',None),' ']) tbl_SymbolicVariables.add_row(['T3',QApplication.translate('HelpDlg','Extra Device #1 channel 1 tare value',None),' ']) tbl_SymbolicVariables.add_row(['T4',QApplication.translate('HelpDlg','Extra Device #1 channel 2 tare value',None),' ']) tbl_SymbolicVariables.add_row(['T5',QApplication.translate('HelpDlg','Extra Device #2 channel 1 tare value',None),' ']) tbl_SymbolicVariables.add_row(['...',QApplication.translate('HelpDlg','...and so forth',None),' ']) tbl_SymbolicVariables.add_row(['E1',QApplication.translate('HelpDlg','Last event value of the first event type',None),' ']) tbl_SymbolicVariables.add_row(['E2',QApplication.translate('HelpDlg','Last event value of the second event type',None),' ']) tbl_SymbolicVariables.add_row(['E3',QApplication.translate('HelpDlg','Last event value of the third event type',None),' ']) tbl_SymbolicVariables.add_row(['E4',QApplication.translate('HelpDlg','Last event value of the fourth event type',None),' ']) tbl_SymbolicVariables.add_row([' ',' ',' ']) tbl_SymbolicVariables.add_row(['R1',QApplication.translate('HelpDlg','ET rate of rise',None),QApplication.translate('HelpDlg','Yes',None)]) tbl_SymbolicVariables.add_row(['R2',QApplication.translate('HelpDlg','BT rate of rise',None),QApplication.translate('HelpDlg','Yes',None)]) tbl_SymbolicVariables.add_row(['RB1',QApplication.translate('HelpDlg','Background ET rate of rise',None),QApplication.translate('HelpDlg','Yes',None)]) tbl_SymbolicVariables.add_row(['RB2',QApplication.translate('HelpDlg','Background BT rate of rise',None),QApplication.translate('HelpDlg','Yes',None)]) strlist.append(tbl_SymbolicVariables.get_html_string(attributes={"width":"100%","border":"1","padding":"1","border-collapse":"collapse"})) strlist.append("<br/><br/><b>") strlist.append(QApplication.translate('HelpDlg','SHIFTED SYMBOLIC VARIABLES',None)) strlist.append("</b>") tbl_ShiftedSymbolicVariablestop = prettytable.PrettyTable() tbl_ShiftedSymbolicVariablestop.header = False tbl_ShiftedSymbolicVariablestop.add_row([QApplication.translate('HelpDlg','The symbolic variables t, b, Y<n>, B<n> and R<n> evaluate to the current value of a sequence of values that define a roast profile. To access earlier or later values one can apply a shift value.',None)+newline+QApplication.translate('HelpDlg','\nFor example, while "Y2" returns the current bean temperature (BT), "Y2[-1]" returns the previous BT temperature and "Y2[-2]" the one before that. Formulas used in the Plotter are applied in sequence to all values, thus there "Y2" points to the current BT temperature processed, "Y2[-1]" the previous BT temperature processed and "Y2[+1]" the next BT temperature to be processed. A positive shift is only available in the Plotter, obviously not during recording.',None)]) strlist.append(tbl_ShiftedSymbolicVariablestop.get_html_string(attributes={"width":"100%","border":"1","padding":"1","border-collapse":"collapse"})) tbl_ShiftedSymbolicVariables = prettytable.PrettyTable() tbl_ShiftedSymbolicVariables.field_names = [QApplication.translate('HelpDlg','Example',None),QApplication.translate('HelpDlg','Description',None)] tbl_ShiftedSymbolicVariables.add_row(['t[+1]',QApplication.translate('HelpDlg','Time one index ahead (plotter only)',None)]) tbl_ShiftedSymbolicVariables.add_row(['t[-3]',QApplication.translate('HelpDlg','Time three indexes delayed',None)]) tbl_ShiftedSymbolicVariables.add_row(['Y1[-2]',QApplication.translate('HelpDlg','ET value delayed by 2 indexes',None)]) tbl_ShiftedSymbolicVariables.add_row(['Y2[+1]',QApplication.translate('HelpDlg','BT value index advanced by one index (plotter only)',None)]) tbl_ShiftedSymbolicVariables.add_row(['B4[-6]',QApplication.translate('HelpDlg','ExtraBackground #1-B delayed 6 indexes',None)]) tbl_ShiftedSymbolicVariables.add_row(['B5[+2]',QApplication.translate('HelpDlg','ExtraBackground #2-A advanced 2 indexes (plotter only)',None)]) tbl_ShiftedSymbolicVariables.add_row(['R1[-2]',QApplication.translate('HelpDlg','ET rate of rise delayed two indexes',None)]) strlist.append(tbl_ShiftedSymbolicVariables.get_html_string(attributes={"width":"100%","border":"1","padding":"1","border-collapse":"collapse"})) strlist.append("<br/><br/><b>") strlist.append(QApplication.translate('HelpDlg','INDEXED SYMBOLIC VARIABLES',None)) strlist.append("</b>") tbl_IndexedSymbolic = prettytable.PrettyTable() tbl_IndexedSymbolic.field_names = [QApplication.translate('HelpDlg','Symbol',None),QApplication.translate('HelpDlg','Description',None)] tbl_IndexedSymbolic.add_row([QApplication.translate('HelpDlg','t, b, Y<n>, B<n> and R<n>',None),QApplication.translate('HelpDlg','Previously recorded data assigned to the symbolic variables t, b, Y<n>, B<n> and R<n> can also directly accessed by index. "Y2{0}" evaluates to the first recorded bean temperature (BT) and "Y2{CHARGE}" to the bean temperature at CHARGE. Additionally, the symbolic variable b can be used to access the recording time at a certain index of the background profile. Thus "b{CHARGE}" returns the recording time at CHARGE of the background profile.',None)]) strlist.append(tbl_IndexedSymbolic.get_html_string(attributes={"width":"100%","border":"1","padding":"1","border-collapse":"collapse"})) strlist.append("<br/><br/><b>") strlist.append(QApplication.translate('HelpDlg','AXIS MAPPING',None)) strlist.append("</b>") tbl_AxisMapping = prettytable.PrettyTable() tbl_AxisMapping.field_names = [QApplication.translate('HelpDlg','Symbol',None),QApplication.translate('HelpDlg','Description',None)] tbl_AxisMapping.add_row(['k',QApplication.translate('HelpDlg','Scaling factor from time to RoR axis. The range of the temperature scale divided by the range of the delta scale. ',None)]) tbl_AxisMapping.add_row(['o',QApplication.translate('HelpDlg','Offset from time to RoR axis. ',None)]) strlist.append(tbl_AxisMapping.get_html_string(attributes={"width":"100%","border":"1","padding":"1","border-collapse":"collapse"})) tbl_AxisMappingbottom = prettytable.PrettyTable() tbl_AxisMappingbottom.header = False tbl_AxisMappingbottom.add_row([QApplication.translate('HelpDlg','Note: RoR values r can be scaled to the temperature axis using a linear approximation of the form "r*k + o". As the variables k and o depend on the actual axis settings which can be changed by the user without triggering a recomputation, those variable are less useful for use in a recording, but useful in the Plotter to plot w.r.t. the RoR y-axis instead of the temperature y-axis.',None)]) strlist.append(tbl_AxisMappingbottom.get_html_string(attributes={"width":"100%","border":"1","padding":"1","border-collapse":"collapse"})) strlist.append("<br/><br/><b>") strlist.append(QApplication.translate('HelpDlg','EVENT INDEX and TIME DELTA',None)) strlist.append("</b>") tbl_EventIndex = prettytable.PrettyTable() tbl_EventIndex.field_names = [QApplication.translate('HelpDlg','Symbol',None),QApplication.translate('HelpDlg','Description',None)] tbl_EventIndex.add_row(['CHARGE, DRY, FCs, FCe, SCs, SCe, DROP',QApplication.translate('HelpDlg','Index of the corresponding event of the profile to retrieve time and values from the corresponding data structures. Evaluates to -1 if not set.',None)]) tbl_EventIndex.add_row(['bCHARGE, bDRY, bFCs, bFCe, bSCs, bSCe, bDROP',QApplication.translate('HelpDlg','Index of the corresponding event of the background profile to retrieve time and values from the corresponding data structures. Evaluates to -1 if not set.',None)]) tbl_EventIndex.add_row([' ',' ']) tbl_EventIndex.add_row(['dCHARGE, dDRY, dFCs, dFCe, dSCs, dSCe, dDROP',QApplication.translate('HelpDlg','Time distance in seconds after the corresponding event. Thus dCHARGE is bound to the current roast time (after CHARGE) in seconds while t is bound to the time in seconds from the start of the recording.',None)]) strlist.append(tbl_EventIndex.get_html_string(attributes={"width":"100%","border":"1","padding":"1","border-collapse":"collapse"})) strlist.append("<br/><br/><b>") strlist.append(QApplication.translate('HelpDlg','AREA UNDER THE CURVE (AUC)',None)) strlist.append("</b>") tbl_AUC = prettytable.PrettyTable() tbl_AUC.field_names = [QApplication.translate('HelpDlg','Symbol',None),QApplication.translate('HelpDlg','Description',None)] tbl_AUC.add_row(['AUCbase',QApplication.translate('HelpDlg','AUC base temperature (could be from the selected event, if set)',None)]) tbl_AUC.add_row(['AUCtarget',QApplication.translate('HelpDlg','AUC target value (could be from the background profile, if set)',None)]) tbl_AUC.add_row(['AUCvalue',QApplication.translate('HelpDlg','the current AUC value. -1 if none available.',None)]) strlist.append(tbl_AUC.get_html_string(attributes={"width":"100%","border":"1","padding":"1","border-collapse":"collapse"})) strlist.append("<br/><br/><b>") strlist.append(QApplication.translate('HelpDlg','PREDICITONS',None)) strlist.append("</b>") tbl_Predictions = prettytable.PrettyTable() tbl_Predictions.field_names = [QApplication.translate('HelpDlg','Symbol',None),QApplication.translate('HelpDlg','Description',None)] tbl_Predictions.add_row(['pDRY',QApplication.translate('HelpDlg','Prediction of the time distance to the DRY event based on the current RoR. Evaluates to -1 on negative RoR and to 0 if the DRY event is already set.',None)]) tbl_Predictions.add_row(['pFCs',QApplication.translate('HelpDlg','Same as pDRY, just for the FCs event.',None)]) strlist.append(tbl_Predictions.get_html_string(attributes={"width":"100%","border":"1","padding":"1","border-collapse":"collapse"})) tbl_Predictionsbottom = prettytable.PrettyTable() tbl_Predictionsbottom.header = False tbl_Predictionsbottom.add_row([QApplication.translate('HelpDlg','Note: The same rules as for the corresponding PhasesLCDs apply to pDRY and pFCs:',None)+newline+QApplication.translate('HelpDlg','\nIf there is no background profile the DRY or FCs bean temperature used for the prediction is taken from the Config>Phases setup.',None)+newline+QApplication.translate('HelpDlg','\nIf there is a background profile and there is DRY or FCs event in the background profile, the DRY or FCs bean temperature used for the prediction is taken from the background profile.',None)+newline+QApplication.translate('HelpDlg','\nException to the above for DRY only: if AutoDRY is checked the DRY temperature used for the prediction is taken from the Config>Phases setup. This does not apply to FCs and AutoFCS.',None)+newline+QApplication.translate('HelpDlg','\nThe prediction value is the calculated time in seconds to reach the DRY or FCs temperature.',None)]) strlist.append(tbl_Predictionsbottom.get_html_string(attributes={"width":"100%","border":"1","padding":"1","border-collapse":"collapse"})) strlist.append("<br/><br/><b>") strlist.append(QApplication.translate('HelpDlg','EXPRESSIONS',None)) strlist.append("</b>") tbl_Expressions = prettytable.PrettyTable() tbl_Expressions.field_names = [QApplication.translate('HelpDlg','Expression',None),QApplication.translate('HelpDlg','Description',None)] tbl_Expressions.add_row(['(<true-expr> if <cond> else <false-expr>)',QApplication.translate('HelpDlg','Conditional. Evaluates to the value of the expression <true-expr> if the condition <cond> holds, otherwise to the value of the expression <false-expr>. The rules of Python are applied to decide if a value holds or not. Thus the boolean values "True" and "False" have the obvious semantic. Any number unequal to 0 evaluates to True and 0 evaluates to False. The value "None" is also evaluated to False.',None)]) strlist.append(tbl_Expressions.get_html_string(attributes={"width":"100%","border":"1","padding":"1","border-collapse":"collapse"})) strlist.append("<br/><br/><b>") strlist.append(QApplication.translate('HelpDlg','MATHEMATICAL FORMULAS',None)) strlist.append("</b>") tbl_MathFormulas = prettytable.PrettyTable() tbl_MathFormulas.field_names = [QApplication.translate('HelpDlg','Formula',None),QApplication.translate('HelpDlg','Description',None)] tbl_MathFormulas.add_row(['abs(x)',QApplication.translate('HelpDlg','Return the absolute value of x.',None)]) tbl_MathFormulas.add_row(['acos(x)',QApplication.translate('HelpDlg','Return the arc cosine (measured in radians) of x.',None)]) tbl_MathFormulas.add_row(['asin(x)',QApplication.translate('HelpDlg','Return the arc sine (measured in radians) of x.',None)]) tbl_MathFormulas.add_row(['atan(x)',QApplication.translate('HelpDlg','Return the arc tangent (measured in radians) of x.',None)]) tbl_MathFormulas.add_row(['cos(x)',QApplication.translate('HelpDlg','Return the cosine of x (measured in radians).',None)]) tbl_MathFormulas.add_row(['degrees(x)',QApplication.translate('HelpDlg','Convert angle x from radians to degrees.',None)]) tbl_MathFormulas.add_row(['exp(x)',QApplication.translate('HelpDlg','Return e raised to the power of x.',None)]) tbl_MathFormulas.add_row(['log(x[, base])',QApplication.translate('HelpDlg','Return the logarithm of x to the given base.',None)]) tbl_MathFormulas.add_row(['min(x1,...,xn)',QApplication.translate('HelpDlg','Return the minimum of the given values.',None)]) tbl_MathFormulas.add_row(['max(x1,...,xn)',QApplication.translate('HelpDlg','Return the maximum of the given values.',None)]) tbl_MathFormulas.add_row(['pow(x, y)',QApplication.translate('HelpDlg','Return x**y (x to the power of y).',None)]) tbl_MathFormulas.add_row(['radians(x)',QApplication.translate('HelpDlg','Convert angle x from degrees to radians.',None)]) tbl_MathFormulas.add_row(['sin(x)',QApplication.translate('HelpDlg','Return the sine of x (measured in radians).',None)]) tbl_MathFormulas.add_row(['sqrt(x)',QApplication.translate('HelpDlg','Return the square root of x.',None)]) tbl_MathFormulas.add_row(['tan(x)',QApplication.translate('HelpDlg','Return the tangent of x (measured in radians).',None)]) strlist.append(tbl_MathFormulas.get_html_string(attributes={"width":"100%","border":"1","padding":"1","border-collapse":"collapse"})) strlist.append("<br/><br/><b>") strlist.append(QApplication.translate('HelpDlg','MATHEMATICAL CONSTANTS',None)) strlist.append("</b>") tbl_Constants = prettytable.PrettyTable() tbl_Constants.field_names = [QApplication.translate('HelpDlg','Symbol',None),QApplication.translate('HelpDlg','Value',None)] tbl_Constants.add_row(['e',2.71828182845904]) tbl_Constants.add_row(['pi',3.14159265358979]) strlist.append(tbl_Constants.get_html_string(attributes={"width":"100%","border":"1","padding":"1","border-collapse":"collapse"})) strlist.append("<br/><br/><b>") strlist.append(QApplication.translate('HelpDlg','PLOTTER EXTENSIONS',None)) strlist.append("</b>") tbl_PlotterExtensionstop = prettytable.PrettyTable() tbl_PlotterExtensionstop.header = False tbl_PlotterExtensionstop.add_row([QApplication.translate('HelpDlg','Note: This section applies only to the Plotter\nUsing math formulas in the plotter also allows to use the symbolic variables P and F (see Signals, Symbolic Assignments and the Plotter).',None)]) strlist.append(tbl_PlotterExtensionstop.get_html_string(attributes={"width":"100%","border":"1","padding":"1","border-collapse":"collapse"})) tbl_PlotterExtensions = prettytable.PrettyTable() tbl_PlotterExtensions.field_names = [QApplication.translate('HelpDlg','Symbol',None),QApplication.translate('HelpDlg','Description',None)] tbl_PlotterExtensions.add_row(['P1...P9',QApplication.translate('HelpDlg','The variables P1,..,P9 represent the results from plot #1,..,#9. You can perform calculations in a later plot on variables of an earlier plot. That way, the plot variables P1,..,P9 allow the cascading or intermediate results. For example, plot #3 can refer to the results of plot 1 using the variable P1.',None)]) tbl_PlotterExtensions.add_row(['F1...F9',QApplication.translate('HelpDlg','F1 refers to the previous result of the actual formula to realize a feedback loop. This is useful in filter designs. Similarly, F2 refers to the second previous result etc.',None)]) strlist.append(tbl_PlotterExtensions.get_html_string(attributes={"width":"100%","border":"1","padding":"1","border-collapse":"collapse"})) strlist.append("</body>") helpstr = "".join(strlist) helpstr = re.sub(r"&", r"&",helpstr) return helpstr
def main(): multiprocessing.set_start_method('spawn') if markups.__version_tuple__ < (2, ): sys.exit('Error: ReText needs PyMarkups 2.0 or newer to run.') # If we're running on Windows without a console, then discard stdout # and save stderr to a file to facilitate debugging in case of crashes. if sys.executable.endswith('pythonw.exe'): sys.stdout = open(devnull, 'w') sys.stderr = open('stderr.log', 'w') try: # See https://github.com/retext-project/retext/issues/399 # and https://launchpad.net/bugs/941826 ctypes.CDLL('libGL.so.1', ctypes.RTLD_GLOBAL) except OSError: pass # Needed for Qt WebEngine on Windows QApplication.setAttribute(Qt.AA_ShareOpenGLContexts) app = QApplication(sys.argv) app.setOrganizationName("ReText project") app.setApplicationName("ReText") app.setApplicationDisplayName("ReText") app.setApplicationVersion(app_version) app.setOrganizationDomain('mitya57.me') if hasattr(app, 'setDesktopFileName'): # available since Qt 5.7 app.setDesktopFileName('me.mitya57.ReText.desktop') QNetworkProxyFactory.setUseSystemConfiguration(True) parser = QCommandLineParser() parser.addHelpOption() parser.addVersionOption() previewOption = QCommandLineOption('preview', QApplication.translate('main', 'Open the files in preview mode')) newWindowOption = QCommandLineOption('new-window', QApplication.translate('main', 'Create a new window even if there is an existing one')) parser.addOption(previewOption) parser.addOption(newWindowOption) parser.addPositionalArgument('files', QApplication.translate('main', 'List of files to open'), '[files...]') parser.process(app) filesToOpen = parser.positionalArguments() initializeDataDirs() RtTranslator = QTranslator() for path in datadirs: if RtTranslator.load('retext_' + globalSettings.uiLanguage, join(path, 'locale')): break QtTranslator = QTranslator() QtTranslator.load("qtbase_" + globalSettings.uiLanguage, QLibraryInfo.location(QLibraryInfo.TranslationsPath)) app.installTranslator(RtTranslator) app.installTranslator(QtTranslator) print('Using configuration file:', settings.fileName()) if globalSettings.appStyleSheet: sheetfile = QFile(globalSettings.appStyleSheet) sheetfile.open(QIODevice.ReadOnly) app.setStyleSheet(QTextStream(sheetfile).readAll()) sheetfile.close() window = ReTextWindow() openInExistingWindow = (globalSettings.openFilesInExistingWindow and not parser.isSet(newWindowOption)) connection = QDBusConnection.sessionBus() if connection.isConnected() and openInExistingWindow: connection.registerObject('/', window, QDBusConnection.ExportAllSlots) serviceName = 'me.mitya57.ReText' if not connection.registerService(serviceName) and filesToOpen: print('Opening the file(s) in the existing window of ReText.') iface = QDBusInterface(serviceName, '/', '', connection) for fileName in filesToOpen: iface.call('openFileWrapper', fileName) qWidgetIface = QDBusInterface(serviceName, '/', 'org.qtproject.Qt.QWidget', connection) qWidgetIface.call('raise') sys.exit(0) window.show() # ReText can change directory when loading files, so we # need to have a list of canonical names before loading fileNames = list(map(canonicalize, filesToOpen)) readStdIn = False if globalSettings.openLastFilesOnStartup: window.restoreLastOpenedFiles() for fileName in fileNames: if QFile.exists(fileName): window.openFileWrapper(fileName) if parser.isSet(previewOption): window.actionPreview.setChecked(True) window.preview(True) elif fileName == '-': readStdIn = True inputData = '' if readStdIn and sys.stdin is not None: if sys.stdin.isatty(): print('Reading stdin, press ^D to end...') inputData = sys.stdin.read() if inputData or not window.tabWidget.count(): window.createNew(inputData) signal.signal(signal.SIGINT, lambda sig, frame: window.close()) sys.exit(app.exec())
GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see <http://www.gnu.org/licenses/>.""" from PyQt5.QtWidgets import QApplication from . import BWRS from . import cubic from .cubic import alfa from . import Grayson_Streed from . import Lee_Kesler from . import virial K = cubic._all + BWRS._all + Lee_Kesler._all + Grayson_Streed._all K_name = [k.__title__.split(" (")[0] for k in K] H = cubic._all + BWRS._all + Lee_Kesler._all H_name = [h.__title__.split(" (")[0] for h in H] mix = ("van der Waals", "Stryjek-Vera", "Panagiotopoulos", "Melhem") cp_ideal = (QApplication.translate("pychemqt", "Ideal"), "DIPPR") __all__ = [BWRS, cubic, Grayson_Streed, Lee_Kesler, virial] # Add references # each submodule must define its custom __doi__ __doi__ = {} for obj in __all__: if "__doi__" in obj.__dict__: __doi__[obj.__name__] = obj.__doi__
def content(): strlist = [] helpstr = '' #@UnusedVariable newline = '\n' #@UnusedVariable strlist.append( '<head><style> td, th {border: 1px solid #ddd; padding: 6px;} th {padding-top: 6px;padding-bottom: 6px;text-align: left;background-color: #0C6AA6; color: white;} </style></head> <body>' ) strlist.append("<b>") strlist.append( QApplication.translate('HelpDlg', 'EVENT CUSTOM BUTTONS', None)) strlist.append("</b>") tbl_Buttons = prettytable.PrettyTable() tbl_Buttons.field_names = [ QApplication.translate('HelpDlg', 'Column', None), QApplication.translate('HelpDlg', 'Description', None) ] tbl_Buttons.add_row([ QApplication.translate('HelpDlg', 'Button Label', None), QApplication.translate( 'HelpDlg', 'Enter \\n to create labels with multiple lines. \\t is substituted by the event type.', None) ]) tbl_Buttons.add_row([ QApplication.translate('HelpDlg', 'Event Description', None), QApplication.translate('HelpDlg', 'Description of the Event to be recorded.', None) ]) tbl_Buttons.add_row([ QApplication.translate('HelpDlg', 'Event Type', None), QApplication.translate( 'HelpDlg', 'Event type to be recorded or leave blank for no event. \u0027\u00B1\u0027 types add a chosen offset (positive or negative) to the present value of the chosen event.', None) ]) tbl_Buttons.add_row([ QApplication.translate('HelpDlg', 'Event Value', None), QApplication.translate('HelpDlg', 'Value of event (1-100) to be recorded.', None) ]) tbl_Buttons.add_row([ QApplication.translate('HelpDlg', 'Action', None), QApplication.translate('HelpDlg', 'Perform an action at the time of the event.', None) ]) tbl_Buttons.add_row([ QApplication.translate('HelpDlg', 'Documentation', None), QApplication.translate( 'HelpDlg', 'The action Command. Depends on the action type, '{}' is replaced by the event value and the offset in case of a \u00B1 event type.', None) ]) tbl_Buttons.add_row([ QApplication.translate('HelpDlg', 'Button Visibility', None), QApplication.translate('HelpDlg', 'Hides/shows individual button.', None) ]) strlist.append( tbl_Buttons.get_html_string( attributes={ "width": "100%", "border": "1", "padding": "1", "border-collapse": "collapse" })) strlist.append("<br/><br/><b>") strlist.append( QApplication.translate('HelpDlg', 'EVENT BUTTONS CONFIGURATION OPTIONS', None)) strlist.append("</b>") tbl_Options = prettytable.PrettyTable() tbl_Options.field_names = [ QApplication.translate('HelpDlg', 'Option', None), QApplication.translate('HelpDlg', 'Description', None) ] tbl_Options.add_row([ QApplication.translate('HelpDlg', 'Max buttons per row', None), QApplication.translate( 'HelpDlg', 'Sets a maximum number of buttons to display on a single row.', None) ]) tbl_Options.add_row([ QApplication.translate('HelpDlg', 'Button size', None), QApplication.translate( 'HelpDlg', 'Sets a size for the buttons. Choices are tiny, small and large.', None) ]) tbl_Options.add_row([ QApplication.translate('HelpDlg', 'Color Pattern', None), QApplication.translate( 'HelpDlg', 'Applies one of 99 autogenerated color patterns to the buttons. Set to "0" to manually choose the button colors.', None) ]) tbl_Options.add_row([ QApplication.translate('HelpDlg', 'Add', None), QApplication.translate( 'HelpDlg', 'Adds a new button to the bottom of the table.', None) ]) tbl_Options.add_row([ QApplication.translate('HelpDlg', 'Insert', None), QApplication.translate( 'HelpDlg', 'Inserts a new button above the selected button.', None) ]) tbl_Options.add_row([ QApplication.translate('HelpDlg', 'Delete', None), QApplication.translate('HelpDlg', 'Deletes the selected button.', None) ]) tbl_Options.add_row([ QApplication.translate('HelpDlg', 'Copy Table', None), QApplication.translate( 'HelpDlg', 'Copy the button table in tab separated format to the clipboard. Option or ALT click to copy a tabular format to the clipboard.', None) ]) tbl_Options.add_row([ QApplication.translate('HelpDlg', 'Help', None), QApplication.translate('HelpDlg', 'Opens this window.', None) ]) strlist.append( tbl_Options.get_html_string( attributes={ "width": "100%", "border": "1", "padding": "1", "border-collapse": "collapse" })) strlist.append("<br/><br/><b>") strlist.append(QApplication.translate('HelpDlg', 'COMMANDS', None)) strlist.append("</b>") tbl_Commandstop = prettytable.PrettyTable() tbl_Commandstop.header = False tbl_Commandstop.add_row([ QApplication.translate( 'HelpDlg', 'Note: "{}" can be used as a placeholder, it will be substituted by the current button value plus the offset for \u00B1 event types. If a placeholder occurs several times in a description/command, all those occurrences are replaced by the value.\n', None) + newline + QApplication.translate( 'HelpDlg', 'Note: commands can be sequenced, separated by semicolons like in “<cmd1>;<cmd2>;<cmd3>”\n', None) + newline + QApplication.translate( 'HelpDlg', 'Note: in PHIDGET commands, the optional parameter <sn> has the form <hub_serial>[:<hub_port>] allows to refer to a specific Phidget HUB by given its serial number, and optionally specifying the port number the addressed module is connected to.\n', None) + newline + QApplication.translate( 'HelpDlg', 'Note: in YOCTOPUCE commands, the optional parameter <sn> holds either the modules serial number or its name', None) ]) strlist.append( tbl_Commandstop.get_html_string( attributes={ "width": "100%", "border": "1", "padding": "1", "border-collapse": "collapse" })) tbl_Commands = prettytable.PrettyTable() tbl_Commands.field_names = [ QApplication.translate('HelpDlg', 'Action', None), QApplication.translate('HelpDlg', 'Command', None), QApplication.translate('HelpDlg', 'Description', None) ] tbl_Commands.add_row([ QApplication.translate('HelpDlg', 'Serial Command', None), QApplication.translate( 'HelpDlg', 'ASCII serial command or binary a2b_uu(serial command)', None), ' ' ]) tbl_Commands.add_row([ QApplication.translate('HelpDlg', 'Call Program', None), QApplication.translate('HelpDlg', 'A program/script path (absolute or relative)', None), QApplication.translate('HelpDlg', 'start an external program', None) ]) tbl_Commands.add_row([ QApplication.translate('HelpDlg', 'Multiple Event', None), QApplication.translate('HelpDlg', 'button numbers separated by a comma: 1,2,..', None), QApplication.translate('HelpDlg', 'triggers other buttons', None) ]) tbl_Commands.add_row([ QApplication.translate('HelpDlg', 'Modbus Command', None), QApplication.translate('HelpDlg', '_', None), QApplication.translate( 'HelpDlg', 'variable holding the last value read via MODBUS', None) ]) tbl_Commands.add_row([ ' ', QApplication.translate('HelpDlg', 'sleep(<float>)', None), QApplication.translate('HelpDlg', 'sleep: add a delay of <float> seconds', None) ]) tbl_Commands.add_row([ ' ', QApplication.translate('HelpDlg', 'button(<bool>)', None), QApplication.translate( 'HelpDlg', 'sets calling button to “pressed” if argument is 1 or True', None) ]) tbl_Commands.add_row([ ' ', QApplication.translate( 'HelpDlg', 'write([slaveId,register,value],..,[slaveId,register,value])', None), QApplication.translate( 'HelpDlg', 'write register: MODBUS function 6 (int) or function 16 (float)', None) ]) tbl_Commands.add_row([ ' ', QApplication.translate('HelpDlg', 'wcoil(slaveId,register,<bool>)', None), QApplication.translate('HelpDlg', 'write coil: MODBUS function 5', None) ]) tbl_Commands.add_row([ ' ', QApplication.translate('HelpDlg', 'wcoils(slaveId,register,[<bool>,..,<bool>])', None), QApplication.translate('HelpDlg', 'write coils: MODBUS function 15', None) ]) tbl_Commands.add_row([ ' ', QApplication.translate( 'HelpDlg', 'mwrite(slaveId,register,andMask,orMask) or mwrite(s,r,am,om,v)', None), QApplication.translate( 'HelpDlg', 'mask write register: MODBUS function 22 or simulates function 22 with function 6 and the given value v', None) ]) tbl_Commands.add_row([ ' ', QApplication.translate( 'HelpDlg', 'writem(slaveId,register,value) or writem(slaveId,register,[<int>,..,<int>])', None), QApplication.translate('HelpDlg', 'write registers: MODBUS function 16', None) ]) tbl_Commands.add_row([ ' ', QApplication.translate( 'HelpDlg', 'writeBCD(s,r,v) or writeBCD([s,r,v],..,[s,r,v])', None), QApplication.translate( 'HelpDlg', 'write 16bit BCD encoded value v to regiseter r of slave s ', None) ]) tbl_Commands.add_row([ ' ', QApplication.translate('HelpDlg', 'writeWord(slaveId,register,value)', None), QApplication.translate( 'HelpDlg', 'write 32bit float to two 16bit int registers: MODBUS function 16', None) ]) tbl_Commands.add_row([ ' ', QApplication.translate( 'HelpDlg', 'writes values to the registers in slaves specified by the given id', None), QApplication.translate( 'HelpDlg', 'writes values to the registers in slaves specified by the given id', None) ]) tbl_Commands.add_row([ QApplication.translate('HelpDlg', 'DTA Command', None), QApplication.translate( 'HelpDlg', 'Insert Data address : value, ex. 4701:1000 and sv is 100. \nAlways multiply with 10 if value Unit: 0.1 / ex. 4719:0 stops heating', None), ' ' ]) tbl_Commands.add_row([ QApplication.translate('HelpDlg', 'IO Command', None), QApplication.translate('HelpDlg', 'set(c,b[,sn])', None), QApplication.translate( 'HelpDlg', 'PHIDGET Binary Output: switches channel c off (b=0) and on (b=1)', None) ]) tbl_Commands.add_row([ ' ', QApplication.translate('HelpDlg', 'toggle(c[,sn])', None), QApplication.translate('HelpDlg', 'PHIDGET Binary Output: toggles channel c', None) ]) tbl_Commands.add_row([ ' ', QApplication.translate('HelpDlg', 'pulse(c,t[,sn])', None), QApplication.translate( 'HelpDlg', 'PHIDGET Binary Output: sets the output of channel c to on for time t in milliseconds', None) ]) tbl_Commands.add_row([ ' ', QApplication.translate('HelpDlg', 'out(c,v[,sn])', None), QApplication.translate( 'HelpDlg', 'PHIDGET Voltage Output: sets voltage output of channel c to v (float)', None) ]) tbl_Commands.add_row([ ' ', QApplication.translate('HelpDlg', 'accel(c,v[,sn])', None), QApplication.translate( 'HelpDlg', 'PHIDGET DCMotor: sets acceleration of channel c to v (float)', None) ]) tbl_Commands.add_row([ ' ', QApplication.translate('HelpDlg', 'vel(c,v[,sn])', None), QApplication.translate( 'HelpDlg', 'PHIDGET DCMotor: sets target velocity of channel c to v (float)', None) ]) tbl_Commands.add_row([ ' ', QApplication.translate('HelpDlg', 'on(c[,sn])', None), QApplication.translate( 'HelpDlg', 'YOCTOPUCE Relay Output: turn channel c of the relay module on', None) ]) tbl_Commands.add_row([ ' ', QApplication.translate('HelpDlg', 'off(c[,sn])', None), QApplication.translate( 'HelpDlg', 'YOCTOPUCE Relay Output: turn channel c of the relay module off', None) ]) tbl_Commands.add_row([ ' ', QApplication.translate('HelpDlg', 'flip(c[,sn])', None), QApplication.translate( 'HelpDlg', 'YOCTOPUCE Relay Output: toggle the state of channel c', None) ]) tbl_Commands.add_row([ ' ', QApplication.translate('HelpDlg', 'pip(c,delay,duration[,sn])', None), QApplication.translate( 'HelpDlg', 'YOCTOPUCE Relay Output: pulse the channel c on after a delay of delay milliseconds for the duration of duration milliseconds', None) ]) tbl_Commands.add_row([ ' ', QApplication.translate('HelpDlg', 'slider(c,v)', None), QApplication.translate('HelpDlg', 'move slider c to value v', None) ]) tbl_Commands.add_row([ ' ', QApplication.translate('HelpDlg', 'button(i,c,b[,sn])', None), QApplication.translate( 'HelpDlg', 'switches channel c off (b=0) and on (b=1) and sets button i to pressed or normal depending on the value b', None) ]) tbl_Commands.add_row([ ' ', QApplication.translate('HelpDlg', 'sleep(<float>)', None), QApplication.translate('HelpDlg', 'sleep: add a delay of <float> seconds', None) ]) tbl_Commands.add_row([ QApplication.translate('HelpDlg', 'Hottop Heater', None), ' ', QApplication.translate('HelpDlg', 'sets heater to value', None) ]) tbl_Commands.add_row([ QApplication.translate('HelpDlg', 'Hottop Fan', None), ' ', QApplication.translate('HelpDlg', 'sets fan to value', None) ]) tbl_Commands.add_row([ QApplication.translate('HelpDlg', 'Hottop Command', None), QApplication.translate( 'HelpDlg', 'motor(n),solenoid(n),stirrer(n),heater(h),fan(f) ', None), QApplication.translate('HelpDlg', 'with n={0 ,1},h={0,..100},f={0,..10}', None) ]) tbl_Commands.add_row([ QApplication.translate('HelpDlg', 'p-i-d', None), ' ', QApplication.translate('HelpDlg', 'configures PID to the values <p>;<i>;<d>', None) ]) tbl_Commands.add_row([ QApplication.translate('HelpDlg', 'Fuji Command', None), QApplication.translate('HelpDlg', 'write(<unitId>,<register>,<value>)', None), ' ' ]) tbl_Commands.add_row([ QApplication.translate('HelpDlg', 'PWM Command', None), QApplication.translate('HelpDlg', 'out(<channel>,<value>[,<sn>])', None), QApplication.translate('HelpDlg', 'PHIDGET PWM Output: <value> in [0-100]', None) ]) tbl_Commands.add_row([ ' ', QApplication.translate('HelpDlg', 'toggle(<channel>[,<sn>])', None), QApplication.translate('HelpDlg', 'PHIDGET PWM Output: toggles <channel>', None) ]) tbl_Commands.add_row([ ' ', QApplication.translate('HelpDlg', 'pulse(<channel>,<millis>[,<sn>])', None), QApplication.translate( 'HelpDlg', 'PHIDGET PWM Output: turn <channel> on for <millis> milliseconds', None) ]) tbl_Commands.add_row([ ' ', QApplication.translate('HelpDlg', 'outhub(<channel>,<value>[,<sn>])', None), QApplication.translate('HelpDlg', 'PHIDGET HUB PWM Output: <value> in [0-100]', None) ]) tbl_Commands.add_row([ ' ', QApplication.translate('HelpDlg', 'togglehub(<channel>[,<sn>])', None), QApplication.translate('HelpDlg', 'PHIDGET HUB PWM Output: toggles <channel>', None) ]) tbl_Commands.add_row([ ' ', QApplication.translate('HelpDlg', 'pulsehub(<channel>,<millis>[,<sn>])', None), QApplication.translate( 'HelpDlg', 'PHIDGET HUB PWM Output: turn <channel> on for <millis> milliseconds', None) ]) tbl_Commands.add_row([ ' ', QApplication.translate('HelpDlg', 'enabled(c,b[,sn])', None), QApplication.translate('HelpDlg', 'YOCTOPUCE PWM Output: PWM running state', None) ]) tbl_Commands.add_row([ ' ', QApplication.translate('HelpDlg', 'freq(c,f[,sn])', None), QApplication.translate( 'HelpDlg', 'YOCTOPUCE PWM Output: set PWM frequency to f (Hz)', None) ]) tbl_Commands.add_row([ ' ', QApplication.translate('HelpDlg', 'duty(c,d[,sn])', None), QApplication.translate( 'HelpDlg', 'YOCTOPUCE PWM Output: set PWM period with the duty cycle in % as a float [0.0-100.0]', None) ]) tbl_Commands.add_row([ ' ', QApplication.translate('HelpDlg', 'move(c,d,t[,sn])', None), QApplication.translate( 'HelpDlg', 'YOCTOPUCE PWM Output: changes progressively the PWM to the specified value over the given time interval', None) ]) tbl_Commands.add_row([ QApplication.translate('HelpDlg', 'VOUT Command', None), QApplication.translate('HelpDlg', 'out(<n>,<v>[,<sn>])', None), QApplication.translate( 'HelpDlg', 'for PHIDGET OUTPUT modules: set analog output channel n to output voltage value v in V (eg. 5.5 for 5.5V)', None) ]) tbl_Commands.add_row([ ' ', QApplication.translate('HelpDlg', 'vout(c,v[,sn])', None), QApplication.translate( 'HelpDlg', 'for YOCTOPUCE VOLTAGE OUT modules with c the channel (1 or 2),v the voltage as float [0.0-10.0]', None) ]) tbl_Commands.add_row([ ' ', QApplication.translate('HelpDlg', 'cout(c[,sn])', None), QApplication.translate( 'HelpDlg', 'for YOCTOPUCE CURRENT OUT modules with c the current as float [3.0-21.0]', None) ]) tbl_Commands.add_row([ ' ', QApplication.translate('HelpDlg', 'sleep(<float>)', None), QApplication.translate('HelpDlg', 'sleep: add a delay of <float> seconds', None) ]) tbl_Commands.add_row([ QApplication.translate('HelpDlg', 'S7 Command', None), QApplication.translate('HelpDlg', '_', None), QApplication.translate('HelpDlg', 'variable holding the last value read via S7', None) ]) tbl_Commands.add_row([ ' ', QApplication.translate('HelpDlg', 'sleep(<float>)', None), QApplication.translate('HelpDlg', 'sleep: add a delay of <float> seconds', None) ]) tbl_Commands.add_row([ ' ', QApplication.translate('HelpDlg', 'getDBbool(<dbnumber>,<start>,<index>)', None), QApplication.translate('HelpDlg', 'read bool from S7 DB', None) ]) tbl_Commands.add_row([ ' ', QApplication.translate('HelpDlg', 'getDBint(<dbnumber>,<start>)', None), QApplication.translate('HelpDlg', 'read int from S7 DB', None) ]) tbl_Commands.add_row([ ' ', QApplication.translate('HelpDlg', 'getDBfloat(<dbnumber>,<start>)', None), QApplication.translate('HelpDlg', 'read float from S7 DB', None) ]) tbl_Commands.add_row([ ' ', QApplication.translate( 'HelpDlg', 'setDBbool(<dbnumber>,<start>,<index>,<value>)', None), QApplication.translate('HelpDlg', 'write bool to S7 DB', None) ]) tbl_Commands.add_row([ ' ', QApplication.translate('HelpDlg', 'setDBint(<dbnumber>,<start>,<value>)', None), QApplication.translate('HelpDlg', 'write int to S7 DB', None) ]) tbl_Commands.add_row([ ' ', QApplication.translate('HelpDlg', 'setDBfloat(<dbnumber>,<start>,<value>)', None), QApplication.translate('HelpDlg', 'write float to S7 DB', None) ]) tbl_Commands.add_row([ QApplication.translate('HelpDlg', 'Aillio R1 Heater', None), ' ', QApplication.translate('HelpDlg', 'sets heater to value', None) ]) tbl_Commands.add_row([ QApplication.translate('HelpDlg', 'Aillio R1 Fan', None), ' ', QApplication.translate('HelpDlg', 'sets fan to value', None) ]) tbl_Commands.add_row([ QApplication.translate('HelpDlg', 'Aillio R1 Drum', None), ' ', QApplication.translate('HelpDlg', 'sets drum speed to value', None) ]) tbl_Commands.add_row([ QApplication.translate('HelpDlg', 'Aillio R1 Command', None), QApplication.translate('HelpDlg', 'PRS', None), QApplication.translate('HelpDlg', 'Sends PRS command', None) ]) tbl_Commands.add_row([ QApplication.translate('HelpDlg', 'Artisan Command', None), QApplication.translate('HelpDlg', 'alarms(<bool>)', None), QApplication.translate('HelpDlg', 'enables/disables alarms', None) ]) tbl_Commands.add_row([ ' ', QApplication.translate('HelpDlg', 'autoCHARGE(<bool>)', None), QApplication.translate('HelpDlg', 'enables/disables autoCHARGE', None) ]) tbl_Commands.add_row([ ' ', QApplication.translate('HelpDlg', 'autoDROP(<bool>)', None), QApplication.translate('HelpDlg', 'enables/disables autoDROP', None) ]) tbl_Commands.add_row([ ' ', QApplication.translate('HelpDlg', 'sleep(<float>)', None), QApplication.translate('HelpDlg', 'sleep: add a delay of <float> seconds', None) ]) tbl_Commands.add_row([ ' ', QApplication.translate('HelpDlg', 'tare(<int>)', None), QApplication.translate( 'HelpDlg', 'tare channel <int> with 1 => ET, 2 => BT, 3 => E1c1, 4: E1c2,..', None) ]) tbl_Commands.add_row([ ' ', QApplication.translate('HelpDlg', 'PIDon', None), QApplication.translate('HelpDlg', 'turns PID on', None) ]) tbl_Commands.add_row([ ' ', QApplication.translate('HelpDlg', 'PIDoff', None), QApplication.translate('HelpDlg', 'turns PID off', None) ]) tbl_Commands.add_row([ ' ', QApplication.translate('HelpDlg', 'PIDtoggle', None), QApplication.translate('HelpDlg', 'toggles the PID state', None) ]) tbl_Commands.add_row([ ' ', QApplication.translate('HelpDlg', 'pidmode(<int>)', None), QApplication.translate( 'HelpDlg', 'sets PID mode to 0: manual, 1: RS, 2: background follow', None) ]) tbl_Commands.add_row([ ' ', QApplication.translate('HelpDlg', 'playbackmode(<int>)', None), QApplication.translate( 'HelpDlg', 'sets playback mode to 0: off, 1: time, 2: BT, 3: ET', None) ]) tbl_Commands.add_row([ ' ', QApplication.translate('HelpDlg', 'openProperties', None), QApplication.translate('HelpDlg', 'opens the Roast Properties dialog', None) ]) tbl_Commands.add_row([ QApplication.translate('HelpDlg', 'RC Command', None), QApplication.translate('HelpDlg', 'pulse(ch,min,max[,sn])', None), QApplication.translate( 'HelpDlg', 'for PHIDGET RC modules: sets the min/max pulse width in microseconds', None) ]) tbl_Commands.add_row([ ' ', QApplication.translate('HelpDlg', 'pos(ch,min,max[,sn])', None), QApplication.translate( 'HelpDlg', 'for PHIDGET RC modules: sets the min/max position', None) ]) tbl_Commands.add_row([ ' ', QApplication.translate('HelpDlg', 'engaged(ch,b[,sn])', None), QApplication.translate( 'HelpDlg', 'for PHIDGET RC modules: engage (b=1) or disengage (b = 0)', None) ]) tbl_Commands.add_row([ ' ', QApplication.translate('HelpDlg', 'ramp(ch,b[,sn])', None), QApplication.translate( 'HelpDlg', 'for PHIDGET RC modules: activates or deactivates the speed ramping state', None) ]) tbl_Commands.add_row([ ' ', QApplication.translate('HelpDlg', 'volt(ch,v[,sn])', None), QApplication.translate( 'HelpDlg', 'for PHIDGET RC modules: set the voltage to one of 5, 6 or 7.4 in Volt', None) ]) tbl_Commands.add_row([ ' ', QApplication.translate('HelpDlg', 'accel(ch,a[,sn])', None), QApplication.translate('HelpDlg', 'for PHIDGET RC modules: set the acceleration', None) ]) tbl_Commands.add_row([ ' ', QApplication.translate('HelpDlg', 'veloc(ch,v[,sn])', None), QApplication.translate('HelpDlg', 'for PHIDGET RC modules: set the velocity', None) ]) tbl_Commands.add_row([ ' ', QApplication.translate('HelpDlg', 'set(ch,pos[,sn])', None), QApplication.translate( 'HelpDlg', 'for PHIDGET RC modules: set the target position', None) ]) tbl_Commands.add_row([ ' ', QApplication.translate('HelpDlg', 'enabled(c,b[,sn])', None), QApplication.translate( 'HelpDlg', 'for YOCTOPUCE RC modules: with c:int the channel, b a bool (eg. enabled(0,1) or enabled(0,True))', None) ]) tbl_Commands.add_row([ ' ', QApplication.translate('HelpDlg', 'move(c,p[,t][,sn])', None), QApplication.translate( 'HelpDlg', 'for YOCTOPUCE RC modules: with c:int the channel, p:int the target position, the optional t the duration in ms, sn the optional modules serial number or logical name', None) ]) tbl_Commands.add_row([ ' ', QApplication.translate('HelpDlg', 'neutral(c,n[,sn])', None), QApplication.translate( 'HelpDlg', 'for YOCTOPUCE RC modules: with n an int [0..65000] in us', None) ]) tbl_Commands.add_row([ ' ', QApplication.translate('HelpDlg', 'range(c,r[,sn])', None), QApplication.translate('HelpDlg', 'for YOCTOPUCE RC modules: with r an int in %', None) ]) tbl_Commands.add_row([ QApplication.translate('HelpDlg', 'WebSocket Command', None), QApplication.translate('HelpDlg', 'send(<json>)', None), QApplication.translate( 'HelpDlg', 'If {} substitutions are used, json brackets need to be duplicated to escape them like in send({{ “value”: {}}})', None) ]) tbl_Commands.add_row([ ' ', QApplication.translate('HelpDlg', 'sleep(<float>)', None), QApplication.translate('HelpDlg', 'sleep: add a delay of <float> seconds', None) ]) strlist.append( tbl_Commands.get_html_string( attributes={ "width": "100%", "border": "1", "padding": "1", "border-collapse": "collapse" })) strlist.append("</body>") helpstr = "".join(strlist) helpstr = re.sub(r"&", r"&", helpstr) return helpstr
def __tr(self, name: str): return QApplication.translate("PrepareMerge", name)
def _trMenuString(string): return QApplication.translate("AppMenu", string)
class TextTool(BaseTool): icon = _path name = QApplication.translate("TextTool", "Text") shortcut = "T" grabKeyboard = True def __init__(self, parent=None): super().__init__(parent) @property def _layoutManager(self): return self.parent().layoutManager() # TODO: we might want to fold this into LayoutManager def _insertUnicodings(self, text): unicodeData = self._font.unicodeData for c in text: glyphName = unicodeData.glyphNameForUnicode(ord(c)) if glyphName is not None: self._layoutManager.insert(glyphName) # methods def toolActivated(self): widget = self.parent() # XXX: don't disable tool on setGlyphs, then uncomment this # self._layoutManager.initCaret() widget.update() def toolDisabled(self): self.parent().update() def drawingAttribute(self, attr, flags): if flags.isActiveLayer: return attr in ("showGlyphFill", "showGlyphComponentFill") return False def drawingColor(self, attr, flags): if attr == "componentFillColor": return Qt.black return None # events def keyPressEvent(self, event): key = event.key() if event.matches(QKeySequence.Paste): # XXX: the menu item should also go down this codepath clipboard = QApplication.clipboard() mimeData = clipboard.mimeData() if mimeData.hasText(): self._insertUnicodings(mimeData.text()) elif key == Qt.Key_Left: # TODO: we'll probably need to reform this stuff for RTL self._layoutManager.caretPrevious() elif key == Qt.Key_Right: self._layoutManager.caretNext() elif key in (Qt.Key_Backspace, Qt.Key_Delete): self._layoutManager.delete(forward=(key == Qt.Key_Delete)) else: text = event.text() if not _isUnicodeChar(text): return # text should be just one codepoint, but be safe self._insertUnicodings(text) def mousePressEvent(self, event): if event.button() == Qt.LeftButton: pos = self.parent().mapFromCanvas(event.localPos()) self._layoutManager.setCaretFromPos(pos) else: super().mousePressEvent(event) def paintBackground(self, painter, index): # XXX: we can't currently draw the caret when there's no # glyph on canvas offset = self._layoutManager.drawingOffset(index) if offset is None: return dx, dy = offset bottom, top = self.parent().verticalBounds() upm = top - bottom painter.save() pen = painter.pen() pen.setColor(QColor(90, 90, 90)) pen.setWidth(0) painter.setPen(pen) painter.translate(dx, bottom + dy) painter.drawLine(-30, -25, 0, 0) painter.drawLine(0, 0, 30, -25) painter.drawLine(0, 0, 0, upm) painter.drawLine(-30, upm + 25, 0, upm) painter.drawLine(0, upm, 30, upm + 25) painter.restore()
class Reactor(equipment): """Clase que define un reactor Parámetros: entrada: Instancia de clase corriente que define la corriente que fluye por la tubería thermal: Comportamiento térmico 0 - Adiabático 1 - Isotérmico 2 - Flujo de calor 3 - Calcular el intercambio de calor conocidas U y Tª externa reaccion: lista con instanacias de clase Reaction P: Presión en el reactor T: temperatura en el reactor Q: Calor transmitido a través de las paredes de la tubería Text: Temperatura en el exterior de la tubería U: Coeficiente global de transimisión de calor entre la tubería y el exterior """ title = QApplication.translate("pychemqt", "Reactor") help = "" kwargs = { "entrada": None, "thermal": 0, "deltaP": 0.0, "Pout": 0.0, "Hmax": 0.0, "eficiencia": 0.0, "poderCalorifico": 0.0, "f_install": 1.3, "Base_index": 0.0, "Current_index": 0.0, "tipo": 0, "subtipo": 0, "material": 0, "P_dis": 0.0 } kwargsInput = ("entrada", ) @property def isCalculable(self): return True def calculo(self): self.entrada = self.kwargs.get("entrada", None) self.thermal = self.kwargs.get("thermal", 0) #TODO: implementar para más de una reacción self.reaccion = self.kwargs.get("reaccion", 0)[0] # P=self.kwargs.get("P", 0) # if P: # self.entrada=Corriente(self.entrada.T, P, self.entrada.caudalmasico.kgh, self.entrada.mezcla, self.entrada.solido) T = self.kwargs.get("T", 0) if T: self.T = unidades.Temperature(T) else: self.T = self.entrada.T self.Q = unidades.Power(self.kwargs.get("Q", 0)) self.Text = self.kwargs.get("Text", 0) self.U = unidades.HeatTransfCoef(self.kwargs.get("U", 0)) if self.thermal in [0, 2]: def f(T): fracciones, h = self.reaccion.conversion(self.entrada, T) corriente = Corriente(T, self.entrada.P.atm, self.entrada.caudalmasico.kgh, Mezcla(self.entrada.ids, fracciones), self.entrada.solido) return corriente.h - self.Q - self.entrada.h - h T = fsolve(f, self.entrada.T) fracciones, h = self.reaccion.conversion(self.entrada, T) elif self.thermal == 1: T = self.T fracciones, h = self.reaccion.conversion(self.entrada, T) elif self.thermal == 3: pass print(fracciones) self.Salida = Corriente(T=T, P=self.entrada.P, caudalMasico=self.entrada.caudalmasico, fraccionMolar=fracciones, solido=self.entrada.solido) self.Heat = unidades.Power(self.Salida.h - self.entrada.h - h)
def content(): strlist = [] helpstr = '' #@UnusedVariable newline = '\n' #@UnusedVariable strlist.append( '<head><style> td, th {border: 1px solid #ddd; padding: 6px;} th {padding-top: 6px;padding-bottom: 6px;text-align: left;background-color: #0C6AA6; color: white;} </style></head> <body>' ) strlist.append("<b>") strlist.append(QApplication.translate('HelpDlg', 'AUTOSAVE FIELDS', None)) strlist.append("</b>") tbl_Autosave = prettytable.PrettyTable() tbl_Autosave.field_names = [ QApplication.translate('HelpDlg', 'Prefix Field', None), QApplication.translate('HelpDlg', 'Source', None), QApplication.translate('HelpDlg', 'Example', None) ] tbl_Autosave.add_row([ '~batchprefix', QApplication.translate('HelpDlg', 'The batch prefix set in Config>Batch>Prefix', None), 'Prod-' ]) tbl_Autosave.add_row([ '~batchcounter', QApplication.translate('HelpDlg', 'The current batch number', None), 653 ]) tbl_Autosave.add_row([ '~batch', QApplication.translate('HelpDlg', 'Same as "~batchprefix~batchnum"', None), 'Prod-653' ]) tbl_Autosave.add_row([ '~batchposition', QApplication.translate( 'HelpDlg', 'The current batch position, or "Roast of the Day"', None), 9 ]) tbl_Autosave.add_row([ '~batch_long', QApplication.translate( 'HelpDlg', 'Same as Batch field in Roast Properties\n"~batchprefix~batchnum (~batchposition)"', None), 'Prod-653 (9)' ]) tbl_Autosave.add_row([ '~title', QApplication.translate('HelpDlg', 'From Roast>Properties>Title', None), 'Ethiopia Guji' ]) tbl_Autosave.add_row([ '~beans_nn', QApplication.translate( 'HelpDlg', 'Replace “nn” with 10, 15, 20, 25, or 30 to show the first “nn” characters of the Beans field.\nFrom Roast>Properties>Beans', None), 'Ethiopia G' ]) tbl_Autosave.add_row([ '~beans_line', QApplication.translate( 'HelpDlg', 'The entire first line From Roast>Properties>Beans', None), 'Ethiopia Guji purchased from Royal' ]) tbl_Autosave.add_row([ '~date', QApplication.translate('HelpDlg', 'Roast date in format yy-MM-dd', None), '20-02-05' ]) tbl_Autosave.add_row([ '~date_long', QApplication.translate('HelpDlg', 'Roast date in format yyyy-MM-dd', None), '2020-02-05' ]) tbl_Autosave.add_row([ '~time', QApplication.translate('HelpDlg', 'Roast time in format hhmm', None), 1742 ]) tbl_Autosave.add_row([ '~datetime', QApplication.translate('HelpDlg', 'Roast date and time in format yy-MM-dd_hhmm', None), '20-02-05_1742' ]) tbl_Autosave.add_row([ '~datetime_long', QApplication.translate( 'HelpDlg', 'Roast date and time in format yyyy-MM-dd_hhmm', None), '2020-02-05_1742' ]) tbl_Autosave.add_row([ '~operator', QApplication.translate('HelpDlg', 'From Roast>Properties>Operator', None), 'Dave' ]) tbl_Autosave.add_row([ '~organization', QApplication.translate('HelpDlg', 'From Roast>Properties>Organization', None), 'Dave's Coffee' ]) tbl_Autosave.add_row([ '~machine', QApplication.translate('HelpDlg', 'From Roast>Properties>Machine', None), 'SF-6' ]) tbl_Autosave.add_row([ '~weight', QApplication.translate('HelpDlg', 'From Roast>Properties>Weight Green', None), 3 ]) tbl_Autosave.add_row([ '~roastedweight', QApplication.translate('HelpDlg', 'From Roast>Properties>Weight Roasted', None), 2.6 ]) tbl_Autosave.add_row([ '~weightunits', QApplication.translate('HelpDlg', 'From Roast>Properties>Weight', None), 'Kg' ]) tbl_Autosave.add_row([ '~weightloss', QApplication.translate( 'HelpDlg', 'Calculated weight loss in percent (the “-” sign is not shown, it can be added manually in front of the field if desired)', None), 14.1 ]) tbl_Autosave.add_row([ '~volume', QApplication.translate('HelpDlg', 'From Roast>Properties>Volume Green', None), 4.1 ]) tbl_Autosave.add_row([ '~roastedvolume', QApplication.translate('HelpDlg', 'From Roast>Properties>Volume Roasted', None), 6.8 ]) tbl_Autosave.add_row([ '~volumeunits', QApplication.translate('HelpDlg', 'From Roast>Properties>Volume', None), 'l' ]) tbl_Autosave.add_row([ '~volumegain', QApplication.translate('HelpDlg', 'Calculated volume gain in percent', None), 61.5 ]) tbl_Autosave.add_row([ '~density', QApplication.translate('HelpDlg', 'From Roast>Properties>Density Green', None), 756.4 ]) tbl_Autosave.add_row([ '~roasteddensity', QApplication.translate('HelpDlg', 'From Roast>Properties>Density Roasted', None), 375.2 ]) tbl_Autosave.add_row([ '~densityunits', QApplication.translate('HelpDlg', 'From Roast>Properties>Density', None), 'g_l' ]) tbl_Autosave.add_row([ '~densityloss', QApplication.translate( 'HelpDlg', 'Calculated density loss in percent (the “-” sign is not shown, it can be added manually in front of the field if desired)', None), 46.8 ]) tbl_Autosave.add_row([ '~moisture', QApplication.translate('HelpDlg', 'From Roast>Properties>Moisture Green', None), 11.7 ]) tbl_Autosave.add_row([ '~roastedmoisture', QApplication.translate('HelpDlg', 'From Roast>Properties>Moisture Roasted', None), 2.8 ]) tbl_Autosave.add_row([ '~moistureloss', QApplication.translate( 'HelpDlg', 'Calculated moisture loss in percent (the “-” sign is not shown, it can be added manually in front of the field if desired)', None), 8.1 ]) tbl_Autosave.add_row([ '~drumspeed', QApplication.translate('HelpDlg', 'From Roast>Properties>Drum Speed', None), 64 ]) tbl_Autosave.add_row([ '~colorwhole', QApplication.translate('HelpDlg', 'From Roast>Properties>Color Whole', None), 103 ]) tbl_Autosave.add_row([ '~colorground', QApplication.translate('HelpDlg', 'From Roast>Properties>Color Ground', None), 98 ]) tbl_Autosave.add_row([ '~colorsystem', QApplication.translate('HelpDlg', 'From Roast>Properties>Color System', None), 'Tonino' ]) tbl_Autosave.add_row([ '~screenmin', QApplication.translate('HelpDlg', 'From Roast>Properties>Screen Min', None), 16 ]) tbl_Autosave.add_row([ '~screenmax', QApplication.translate('HelpDlg', 'From Roast>Properties>Screen Max', None), 18 ]) tbl_Autosave.add_row([ '~greenstemp', QApplication.translate( 'HelpDlg', 'From Roast>Properties>(Green) Beans Temperature', None), '68.0' ]) tbl_Autosave.add_row([ '~ambtemp', QApplication.translate('HelpDlg', 'From Roast>Properties>Ambient Temperature', None), '70.0' ]) tbl_Autosave.add_row([ '~ambhumidity', QApplication.translate('HelpDlg', 'From Roast>Properties>Ambient Humidity', None), 35.1 ]) tbl_Autosave.add_row([ '~ambpressure', QApplication.translate('HelpDlg', 'From Roast>Properties>Ambient Pressure', None), 1023.8 ]) tbl_Autosave.add_row([ '~devtime', QApplication.translate('HelpDlg', 'Calculated time from FCs to DROP in seconds', None), 112 ]) tbl_Autosave.add_row([ '~devtime_long', QApplication.translate('HelpDlg', 'Calculated time from FCs to DROP in min_secs', None), '01_52' ]) tbl_Autosave.add_row([ '~dtr', QApplication.translate('HelpDlg', 'From Profile Statistics - DTR (in percent)', None), 22.1 ]) tbl_Autosave.add_row([ '~auc', QApplication.translate('HelpDlg', 'From the Profile Statistics - AUC', None), 218 ]) tbl_Autosave.add_row([ '~aucbase', QApplication.translate('HelpDlg', 'From the Profile Statistics - AUC Base', None), 300 ]) tbl_Autosave.add_row([ '~chargeet', QApplication.translate('HelpDlg', 'From the Profile - ET at CHARGE', None), 379.4 ]) tbl_Autosave.add_row([ '~chargebt', QApplication.translate('HelpDlg', 'From the Profile - BT at CHARGE', None), 375.2 ]) tbl_Autosave.add_row([ '~fcset', QApplication.translate('HelpDlg', 'From the Profile - ET at FCs', None), 397.4 ]) tbl_Autosave.add_row([ '~fcsbt', QApplication.translate('HelpDlg', 'From the Profile -BT at FCs', None), 386.7 ]) tbl_Autosave.add_row([ '~dropet', QApplication.translate('HelpDlg', 'From the Profile - ET at DROP', None), 378.6 ]) tbl_Autosave.add_row([ '~dropbt', QApplication.translate('HelpDlg', 'From the Profile - BT at DROP', None), 412.5 ]) tbl_Autosave.add_row([ '~droptime', QApplication.translate('HelpDlg', 'From the Profile - DROP time in seconds', None), 617 ]) tbl_Autosave.add_row([ '~droptime_long', QApplication.translate('HelpDlg', 'From the Profile - DROP time in min_secs', None), '10_17' ]) tbl_Autosave.add_row([ '~roastingnotes_nn', QApplication.translate( 'HelpDlg', 'Replace “nn” with 10, 15, 20, 25, or 30 to show the first “nn” characters of the Roasting Notes field.\nFrom Roast>Properties>Roasting Notes', None), 'No crash, ' ]) tbl_Autosave.add_row([ '~roastingnotes_line', QApplication.translate( 'HelpDlg', 'The entire first line From Roast>Properties>Roasting Notes', None), 'No crash, maintained RoR' ]) tbl_Autosave.add_row([ '~cupptingnotes_nn', QApplication.translate( 'HelpDlg', 'Replace “nn” with 10, 15, 20, 25, or 30 to show the first “nn” characters of the Cupping Notes field.\nFrom Roast>Properties>Cupping Notes', None), 'Lots of be' ]) tbl_Autosave.add_row([ '~cupptingnotes_line', QApplication.translate( 'HelpDlg', 'The entire first line From Roast>Properties>Cupping Notes', None), 'Lots of berries and chocolate' ]) strlist.append( tbl_Autosave.get_html_string( attributes={ "width": "100%", "border": "1", "padding": "1", "border-collapse": "collapse" })) tbl_Autosavebottom = prettytable.PrettyTable() tbl_Autosavebottom.header = False tbl_Autosavebottom.add_row([ 'NOTES:\nAnything between single quotes ' will show in the file name only when ON.\nExample: 'REC ~batch'\n\nAnything between double quotes " will show in the file name only when OFF. \nExample: "~operator"\n\nFor backward compatibility, when the Prefix field is text only the date and time are appended to the file name.\nExample: 'Autosave' will result in file name 'Autosave_20-01-13_1705'.\nTo show only the text place a single '!' at the start of the Prefix field\nExample: '!Autosave' will result in file name 'Autosave'.\n\nTo maintain cross platform compatibility, file names may contain only letters, numbers, spaces, \nand the following special characters: \n_ - . ( )' ]) strlist.append( tbl_Autosavebottom.get_html_string( attributes={ "width": "100%", "border": "1", "padding": "1", "border-collapse": "collapse" })) strlist.append("<br/><br/><b>") strlist.append(QApplication.translate('HelpDlg', 'EXAMPLES', None)) strlist.append("</b>") tbl_Examplestop = prettytable.PrettyTable() tbl_Examplestop.header = False tbl_Examplestop.add_row([ QApplication.translate( 'HelpDlg', 'Data used to replace the fields in the Autosave File Name Prefix are pulled from the current Roast Properties. ', None) ]) strlist.append( tbl_Examplestop.get_html_string( attributes={ "width": "100%", "border": "1", "padding": "1", "border-collapse": "collapse" })) tbl_Examples = prettytable.PrettyTable() tbl_Examples.field_names = [ QApplication.translate('HelpDlg', 'Autosave Field', None), QApplication.translate('HelpDlg', 'Example File Name', None) ] tbl_Examples.add_row([ QApplication.translate('HelpDlg', '~title Roasted on ~date', None), QApplication.translate('HelpDlg', 'Burundi Roasted on 20-04-25.alog', None) ]) tbl_Examples.add_row([ QApplication.translate('HelpDlg', '~batchcounter ~title ~date_long', None), QApplication.translate('HelpDlg', '1380 Burundi 2020-04-25_1136.alog', None) ]) tbl_Examples.add_row([ QApplication.translate( 'HelpDlg', '~beans ~machine ~drumspeedRPM ~weight~weightunits ~poisturePCT ~operator ~date ~batch(~batchposition)', None), QApplication.translate( 'HelpDlg', 'Burundi Kiganda Murambi Lot44 SF-25 64RPM 10.3Kg 10.2PCT Roberto 20-04-25 Prod-1380(6).alog', None) ]) tbl_Examples.add_row([ QApplication.translate( 'HelpDlg', '\u0027Recording ~batchcounter' "~batch" ~title ~datetime_long', None), QApplication.translate( 'HelpDlg', 'When OFF:\nProd-1380 Burundi Kiganda Murambi 2020-04-25_1136.alog\nWhile Recording:\nRecording 1380 Burundi KigandaMurambi 2020-04-25_1136.alog', None) ]) strlist.append( tbl_Examples.get_html_string( attributes={ "width": "100%", "border": "1", "padding": "1", "border-collapse": "collapse" })) strlist.append("</body>") helpstr = "".join(strlist) helpstr = re.sub(r"&", r"&", helpstr) return helpstr
def readBool(self, area, dbnumber, start, index, force=False): if area == 0: return try: #### lock shared resources ##### self.COMsemaphore.acquire(1) if not force and area in self.readingsCache and dbnumber in self.readingsCache[ area] and start in self.readingsCache[area][dbnumber]: # cache hit res = bytearray([self.readingsCache[area][dbnumber][start]]) r = self.get_bool(res, 0, index) if self.aw.seriallogflag: self.aw.addserial( "S7 readBool_cached({},{},{},{},{}) => {}".format( area, dbnumber, start, index, force, r)) return r else: self.connect() if self.isConnected(): retry = self.readRetries res = None while True: self.waitToEnsureMinTimeBetweenRequests() try: with suppress_stdout_stderr(): res = self.plc.read_area( self.areas[area], dbnumber, start, 1) except Exception: res = None if res is None: if retry > 0: retry = retry - 1 else: raise Exception("result None") else: break if res is None: return else: if self.commError: # we clear the previous error and send a message self.commError = False self.aw.qmc.adderror( QApplication.translate( "Error Message", "S7 Communication Resumed", None)) r = self.get_bool(res, 0, index) if self.aw.seriallogflag: self.aw.addserial( "S7 readBool({},{},{},{},{}) => {}".format( area, dbnumber, start, index, force, r)) return r else: self.commError = True self.aw.qmc.adderror( QApplication.translate( "Error Message", "S7 Error: connecting to PLC failed", None)) except Exception as e: if self.aw.qmc.flagon: _, _, exc_tb = sys.exc_info() self.aw.qmc.adderror( QApplication.translate("Error Message", "S7 Communication Error", None) + " readBool({},{},{},{},{}): {}".format( area, dbnumber, start, index, force, str(e)), exc_tb.tb_lineno) if self.aw.seriallogflag: self.aw.addserial( "S7 readBool({},{},{},{},{}) => S7 Communication Error: {}" .format(area, dbnumber, start, index, force, str(e))) self.commError = True finally: if self.COMsemaphore.available() < 1: self.COMsemaphore.release(1)
def readActiveRegisters(self): if not self.optimizer: return try: #### lock shared resources ##### self.COMsemaphore.acquire(1) self.clearReadingsCache() self.connect() if self.isConnected(): for area in self.activeRegisters: for db_nr in self.activeRegisters[area]: registers = sorted(self.activeRegisters[area][db_nr]) if self.fetch_max_blocks: sequences = [[registers[0], registers[-1]]] else: # split in successive sequences gaps = [[s, e] for s, e in zip(registers, registers[1:]) if s + 1 < e] edges = iter(registers[:1] + sum(gaps, []) + registers[-1:]) sequences = list( zip(edges, edges) ) # list of pairs of the form (start-register,end-register) for seq in sequences: retry = self.readRetries register = seq[0] count = seq[1] - seq[0] + 1 res = None while True: self.waitToEnsureMinTimeBetweenRequests() try: res = self.plc.read_area( self.areas[area], db_nr, register, count) except: res = None if res is None: if retry > 0: retry = retry - 1 else: raise Exception( "read_area({},{},{},{})".format( area, db_nr, register, count)) else: break if res is not None: if self.commError: # we clear the previous error and send a message self.commError = False self.aw.qmc.adderror( QApplication.translate( "Error Message", "S7 Communication Resumed", None)) self.cacheReadings(area, db_nr, register, res) #note: logged chars should be unicode not binary if self.aw.seriallogflag: self.aw.addserial( "S7 read_area({},{},{},{})".format( area, db_nr, register, count)) except Exception as e: # as ex: # self.disconnect() # import traceback # traceback.print_exc(file=sys.stdout) # _, _, exc_tb = sys.exc_info() # self.aw.qmc.adderror((QApplication.translate("Error Message","S7 Error:",None) + " readSingleRegister() {0}").format(str(ex)),exc_tb.tb_lineno) _, _, exc_tb = sys.exc_info() self.aw.qmc.adderror( QApplication.translate( "Error Message", "readActiveRegisters() S7 Communication Error", None) + ": " + str(e), exc_tb.tb_lineno) if self.aw.seriallogflag: self.aw.addserial( "S7 readActiveRegisters() => S7 Communication Error: {}". format(str(e))) self.commError = True finally: if self.COMsemaphore.available() < 1: self.COMsemaphore.release(1)
def connect(self): if not self.libLoaded: #from artisanlib.s7client import S7Client from snap7.common import load_library as load_snap7_library # first load shared lib if needed platf = str(platform.system()) if platf in ['Windows', 'Linux'] and artisanlib.util.appFrozen(): libpath = os.path.dirname(sys.executable) if platf == 'Linux': snap7dll = os.path.join(libpath, "libsnap7.so") else: # Windows: snap7dll = os.path.join(libpath, "snap7.dll") load_snap7_library( snap7dll) # will ensure to load it only once self.libLoaded = True if self.libLoaded and self.plc is None: # create a client instance from artisanlib.s7client import S7Client self.plc = S7Client() # next reset client instance if not yet connected to ensure a fresh start if not self.isConnected(): try: if self.plc is None: from artisanlib.s7client import S7Client self.plc = S7Client() else: self.plc.disconnect() except: pass with suppress_stdout_stderr(): time.sleep(0.2) try: self.plc.connect(self.host, self.rack, self.slot, self.port) time.sleep(0.2) except: pass if self.isConnected(): self.is_connected = True self.aw.sendmessage( QApplication.translate("Message", "S7 connected", None)) self.clearReadingsCache() time.sleep(0.1) else: self.disconnect() time.sleep(0.3) from artisanlib.s7client import S7Client self.plc = S7Client() # we try a second time with suppress_stdout_stderr(): time.sleep(0.3) self.plc.connect(self.host, self.rack, self.slot, self.port) time.sleep(0.3) if self.isConnected(): self.is_connected = True self.clearReadingsCache() self.aw.sendmessage( QApplication.translate("Message", "S7 Connected", None) + " (2)") time.sleep(0.1) self.updateActiveRegisters()
class BaseTool(QObject): name = QApplication.translate("BaseTool", "Tool") cursor = QCursor() iconPath = None def __init__(self, parent=None): super().__init__(parent) def toolActivated(self): pass def toolDisabled(self): pass @property def _glyph(self): return self.parent().glyph() # helper functions def clampToOrigin(self, pos, origin): deltaX = pos.x() - origin.x() deltaY = pos.y() - origin.y() # go into the first quadrant to simplify our study aDeltaX = abs(deltaX) aDeltaY = abs(deltaY) if aDeltaY >= aDeltaX * 2: pos.setX(origin.x()) elif aDeltaY > aDeltaX / 2: avg = (aDeltaX + aDeltaY) / 2 pos.setX(origin.x() + copysign(avg, deltaX)) pos.setY(origin.y() + copysign(avg, deltaY)) else: pos.setY(origin.y()) return pos def magnetPos(self, pos): widget = self.parent() itemTuple = widget.itemAt(pos) if itemTuple is not None: itemUnderMouse, parent = itemTuple if parent is not None: pos.setX(itemUnderMouse.x) pos.setY(itemUnderMouse.y) return pos # events def keyPressEvent(self, event): pass def keyReleaseEvent(self, event): pass def mousePressEvent(self, event): pass def mouseMoveEvent(self, event): pass def mouseReleaseEvent(self, event): pass def mouseDoubleClickEvent(self, event): pass # custom painting def paint(self, painter): pass
class Solid(Entity): """Class to define a solid entity Parameters: tipo: definition of solid 0 - Undefined 1 - Mean diameter 2 - Particle solid distribution kwargs: caudalSolido diametroMedio fraccionMasica diametros T solidos: To override the config value """ kwargs = {"caudalSolido": [], "diametroMedio": 0.0, "distribucion_fraccion": [], "distribucion_diametro": [], "solids": None} status = 0 msg = QApplication.translate("pychemqt", "undefined") def __call__(self, **kwargs): """All equipment are callables, so we can instance or add/change input value with flexibility""" Entity.__call__(self, **kwargs) if self._oldkwargs != self.kwargs and self.isCalculable: self.calculo() @property def isCalculable(self): self.status = 0 if sum(self.kwargs["caudalSolido"]) > 0: if self.kwargs["distribucion_fraccion"] and \ self.kwargs["distribucion_diametro"]: self.status = 2 elif self.kwargs["diametroMedio"]: self.status = 1 return self.status def calculo(self): if self.kwargs["solids"] is not None: self.ids = self.kwargs["solids"] else: Config = getMainWindowConfig() txt = Config.get("Components", "Solids") if isinstance(txt, str): self.ids = eval(txt) else: self.ids = txt self.componente = [Componente(int(i)) for i in self.ids] caudal = self.kwargs.get("caudalSolido", []) diametro_medio = self.kwargs.get("diametroMedio", 0.0) fraccion = self.kwargs.get("distribucion_fraccion", []) diametros = self.kwargs.get("distribucion_diametro", []) if self.status == 0: self._bool = False return else: self._bool = True self.caudalUnitario = [MassFlow(i) for i in caudal] self.caudal = MassFlow(sum(self.caudalUnitario)) self.diametros = diametros self.fracciones = fraccion if self.status == 2: self.diametros = [Length(i, "m", magnitud="ParticleDiameter") for i in diametros] self.fracciones = fraccion diametro_medio = 0 self.fracciones_acumuladas = [0] for di, xi in zip(diametros, fraccion): diametro_medio += di*xi self.fracciones_acumuladas.append( xi+self.fracciones_acumuladas[-1]) del self.fracciones_acumuladas[0] self.diametro_medio = Length(diametro_medio, magnitud="ParticleDiameter") self.RhoS(self.kwargs.get("T", 300)) def RhoS(self, T): densidad = 0 for i in range(len(self.ids)): densidad += self.caudalUnitario[i]/self.caudal * \ self.componente[i].RhoS(T) self.rho = Density(densidad) self.T = Temperature(T) def __repr__(self): if self.status: return "Solid with %s and dm %s" % (self.caudal.str, self.diametro_medio.str) else: return "%s empty" % (self.__class__) def ajustar_distribucion(self, eq=0): """ Fit current distribution with any of standard. eq: index with distribuciont to fit 0 - Rosin, Rammler, Sperling (Weibull distribution) 1 - Gates, Gaudin, Shumann 2 - Gaudin, Meloy 3 - Broadbent, Callcott 4 - Distribución lognormal 5 - Harris Ref: Ahmed, Drzymala; Two-dimensional fractal linearization of distribution curves, pag 2 """ d = r_[self.diametros] y = r_[self.fracciones_acumuladas] if eq == 0: model = "Rosin, Rammler, Sperling" inicio = r_[1, 1] def function(p, d): return 1.-exp(-(d/p[0])**p[1]) elif eq == 1: model = "Gates, Gaudin, Shumann" inicio = r_[1, 1] def function(p, d): return (d/p[0])**p[1] elif eq == 2: model = "Gaudin, Meloy" inicio = r_[d[-1]*2, 0] def function(p, d): return 1-(1-d/p[0])**p[1] elif eq == 3: model = "Broadbent, Callcott" inicio = r_[1, 1] def function(p, d): return 1.-exp(-(d/p[0])**p[1])/(1-exp(-1.)) elif eq == 4: model = "lognormal" inicio = r_[1, 1] def function(p, d): return erf(log(d/p[0])/p[1]) elif eq == 5: model = "Harris" inicio = r_[d[-1]*2, 1, 1] def function(p, d): return 1-(1-d/p[0]**p[1])**p[2] def residuo(p, d, y): return function(p, d) - y ajuste, exito = leastsq(residuo, inicio, args=(d, y)) return d, function(ajuste, d), model def Separar(self, etas): """Split solid with efficiency array input return two array with solids filtered and no filtered""" rendimiento_global = 0 for i, fraccion in enumerate(self.fracciones): rendimiento_global += etas[i]*fraccion G_skip = MassFlow(self.caudal*(1-rendimiento_global)) G_sep = MassFlow(self.caudal*rendimiento_global) if rendimiento_global == 1: return None, self elif rendimiento_global == 0: return self, None else: f_gas = [] f_solid = [] for i in range(len(self.diametros)): f_gas.append(self.caudal*self.fracciones[i]*(1-etas[i])/G_skip) f_solid.append(self.caudal*self.fracciones[i]*etas[i]/G_sep) S_skip = Solid(caudalSolido=[G_skip], distribucion_diametro=self.diametros, distribucion_fraccion=f_gas) S_sep = Solid(caudalSolido=[G_sep], distribucion_diametro=self.diametros, distribucion_fraccion=f_solid) return S_skip, S_sep def writeStatetoJSON(self, solid): if self.status: solid["status"] = self.status solid["ids"] = self.ids solid["unitFlow"] = self.caudalUnitario solid["caudal"] = self.caudal solid["diametros"] = self.diametros solid["fracciones"] = self.fracciones solid["fracciones_acumuladas"] = self.fracciones_acumuladas solid["diametro_medio"] = self.diametro_medio solid["rho"] = self.rho solid["T"] = self.T def readStatefromJSON(self, solid): if solid: self._bool = True self.status = solid["status"] self.ids = solid["ids"] self.componente = [Componente(int(i)) for i in self.ids] self.caudalUnitario = [MassFlow(q) for q in solid["unitFlow"]] self.caudal = MassFlow(solid["caudal"]) self.diametros = [Length(d, "m", "ParticleDiameter") for d in solid["diametros"]] self.fracciones = solid["fracciones"] self.fracciones_acumuladas = solid["fracciones_acumuladas"] self.diametro_medio = Length(solid["diametro_medio"]) self.rho = Density(solid["rho"]) self.T = Temperature(solid["T"]) else: self._bool = False self.status = False
def __init__(self, parent=None, aw=None): super(autosaveDlg, self).__init__(parent, aw) self.setModal(True) self.setWindowTitle( QApplication.translate("Form Caption", "Autosave", None)) settings = QSettings() if settings.contains("autosaveGeometry"): self.restoreGeometry(settings.value("autosaveGeometry")) self.helpdialog = None self.prefixEdit = QLineEdit(self.aw.qmc.autosaveprefix) self.prefixEdit.setToolTip( QApplication.translate("Tooltip", "Automatic generated name", None)) self.prefixEdit.textChanged.connect(self.prefixChanged) prefixpreviewLabel = QLabel() prefixpreviewLabel.setAlignment( Qt.Alignment(Qt.AlignCenter | Qt.AlignRight)) prefixpreviewLabel.setText( QApplication.translate("Label", "Preview:", None)) self.prefixPreview = QLabel() self.prefixpreviewrecordingLabel = QLabel() self.prefixpreviewrecordingLabel.setAlignment( Qt.Alignment(Qt.AlignCenter | Qt.AlignRight)) self.prefixPreviewrecording = QLabel() self.prefixChanged() autochecklabel = QLabel( QApplication.translate("CheckBox", "Autosave [a]", None)) self.autocheckbox = QCheckBox() self.autocheckbox.setToolTip( QApplication.translate( "Tooltip", "ON/OFF of automatic saving when pressing keyboard letter [a]", None)) self.autocheckbox.setChecked(self.aw.qmc.autosaveflag) autopdflabel = QLabel( QApplication.translate("CheckBox", "Save also", None)) self.autopdfcheckbox = QCheckBox() self.autopdfcheckbox.setToolTip( QApplication.translate("Tooltip", "Save image alongside .alog profiles", None)) self.autopdfcheckbox.setChecked(self.aw.qmc.autosaveimage) imageTypes = ["PDF", "SVG", "PNG", "JPEG", "BMP", "CSV", "JSON"] self.imageTypesComboBox = QComboBox() self.imageTypesComboBox.addItems(imageTypes) self.imageTypesComboBox.setCurrentIndex( imageTypes.index(self.aw.qmc.autosaveimageformat)) prefixlabel = QLabel() prefixlabel.setAlignment(Qt.Alignment(Qt.AlignBottom | Qt.AlignRight)) prefixlabel.setText( QApplication.translate("Label", "File Name Prefix", None)) # connect the ArtisanDialog standard OK/Cancel buttons self.dialogbuttons.accepted.connect(self.autoChanged) self.dialogbuttons.rejected.connect(self.close) self.helpButton = self.dialogbuttons.addButton(QDialogButtonBox.Help) self.dialogbuttons.button(QDialogButtonBox.Help).clicked.connect( self.showautosavehelp) pathButton = QPushButton(QApplication.translate( "Button", "Path", None)) pathButton.setFocusPolicy(Qt.NoFocus) self.pathEdit = QLineEdit(self.aw.qmc.autosavepath) self.pathEdit.setToolTip( QApplication.translate( "Tooltip", "Sets the directory to store batch profiles when using the letter [a]", None)) pathButton.clicked.connect(self.getpath) pathAlsoButton = QPushButton( QApplication.translate("Button", "Path", None)) pathAlsoButton.setFocusPolicy(Qt.NoFocus) self.pathAlsoEdit = QLineEdit(self.aw.qmc.autosavealsopath) self.pathAlsoEdit.setToolTip( QApplication.translate( "Tooltip", "Sets the directory to store the save also files", None)) pathAlsoButton.clicked.connect(self.getalsopath) buttonLayout = QHBoxLayout() buttonLayout.addWidget(self.dialogbuttons) autolayout = QGridLayout() autolayout.addWidget(self.autocheckbox, 0, 0, Qt.AlignRight) autolayout.addWidget(autochecklabel, 0, 1) autolayout.addWidget(prefixlabel, 1, 0) autolayout.addWidget(self.prefixEdit, 1, 1, 1, 2) autolayout.addWidget(prefixpreviewLabel, 2, 0) autolayout.addWidget(self.prefixPreview, 2, 1) autolayout.addWidget(self.prefixpreviewrecordingLabel, 3, 0) autolayout.addWidget(self.prefixPreviewrecording, 3, 1) autolayout.addWidget(pathButton, 4, 0) autolayout.addWidget(self.pathEdit, 4, 1, 1, 2) autolayout.addWidget(self.autopdfcheckbox, 5, 0, Qt.AlignRight) autolayout.addWidget(autopdflabel, 5, 1) autolayout.addWidget(self.imageTypesComboBox, 5, 2) autolayout.addWidget(pathAlsoButton, 6, 0) autolayout.addWidget(self.pathAlsoEdit, 6, 1, 1, 2) autolayout.setColumnStretch(0, 0) autolayout.setColumnStretch(1, 10) autolayout.setColumnStretch(2, 0) mainLayout = QVBoxLayout() mainLayout.addLayout(autolayout) mainLayout.addStretch() mainLayout.addSpacing(10) mainLayout.addLayout(buttonLayout) self.setLayout(mainLayout) self.dialogbuttons.button(QDialogButtonBox.Ok).setFocus()
3: { "autor": "Bell, I.H., Jäger, A.", "title": "Helmholtz Energy Transformations of Common Cubic Equations " "of State for Use with Pure Fluids and Mixtures", "ref": "J. Res. of NIST 121 (2016) 236-263", "doi": "10.6028/jres.121.011" }, 4: { "autor": "", "title": "", "ref": "", "doi": "" }, } alfa = (QApplication.translate("pychemqt", "Original"), "Boston-Mathias", "Twu", "Doridon") @refDoc(__doi__, [3]) def CubicHelmholtz(tau, delta, **kw): r"""Residual contribution to the free Helmholtz energy from a generic cubic equation of state with the form: .. math:: P = \frac{RT}{V-b}-\frac{\alpha(T)}{\left(v+\Delta_1b\right) \left(v+\Delta_2b\right)} From this formulation it's possible calculate the Helmholtz free energy with the equation: .. math::
def retranslateUi(self, PythonCheatSheet): PythonCheatSheet.setWindowTitle(QApplication.translate("PythonCheatSheet", "Python Cheat Sheet", None)) self.BasicsGroupBox.setTitle(QApplication.translate("PythonCheatSheet", "Basics", None )) self.conditionals_button.setText(QApplication.translate("PythonCheatSheet", "Conditionals", None )) self.strings_button.setText(QApplication.translate("PythonCheatSheet", "Strings", None )) self.expressions_button.setText(QApplication.translate("PythonCheatSheet", "Expressions", None )) self.lists_button.setText(QApplication.translate("PythonCheatSheet", "Lists", None )) self.keywords_button.setText(QtWidgets.QApplication.translate("PythonCheatSheet", "Keywords", None)) self.Important.setTitle(QApplication.translate("PythonCheatSheet", "Important", None )) self.decorators_button.setText(QApplication.translate("PythonCheatSheet", "Decorators", None )) self.examples_button.setText(QApplication.translate("PythonCheatSheet", "Examples", None )) self.yield_button.setText(QApplication.translate("PythonCheatSheet", "Yield", None )) self.exceptions_button.setText(QApplication.translate("PythonCheatSheet", "Exceptions", None )) self.twisted_button.setText(QApplication.translate("PythonCheatSheet", "Twisted", None )) self.search_label.setText(QApplication.translate("PythonCheatSheet", "Search", None )) self.clear_button.setText(QApplication.translate("PythonCheatSheet", "Clear", None ))
class PsyState(object): """ Class to model a psychrometric state with properties kwargs definition parameters: P: Pressure, Pa z: altitude, m tdp: dew-point temperature tdb: dry-bulb temperature twb: web-bulb temperature w: Humidity Ratio [kg water/kg dry air] HR: Relative humidity h: Mixture enthalpy v: Mixture specified volume P: mandatory input for barometric pressure, z as an alternative P input it needs other two input parameters: 0 - tdb, w 1 - tdb, HR 2 - tdb, twb 3 - tdb, tdp 4 - tdp, HR 5 - tdp, twb 6 - twb, w """ kwargs = {"z": 0.0, "P": 0.0, "tdb": 0.0, "tdb": 0.0, "twb": 0.0, "w": None, "HR": None, "h": None, "v": 0.0} status = 0 msg = "Unknown variables" TEXT_MODE = [ QApplication.translate("pychemqt", "T dry bulb, Humidity Ratio"), QApplication.translate("pychemqt", "T dry bulb, Relative humidity"), QApplication.translate("pychemqt", "T dry bulb, T wet bulb"), QApplication.translate("pychemqt", "T dry bulb, T dew point"), QApplication.translate("pychemqt", "T dew point, Relative humidity"), QApplication.translate("pychemqt", "T wet bulb, Relative humidity") ] VAR_NAME = [ ("tdb", "w"), ("tdb", "HR"), ("tdb", "twb"), ("tdb", "tdp"), ("tdp", "HR"), ("twb", "HR") ] # QApplication.translate("pychemqt", "T dry bulb, Enthalpy")) # QApplication.translate("pychemqt", "Tª bulbo seco, Densidad")) # QApplication.translate("pychemqt", "Tª bulbo húmedo, H absoluta")) # QApplication.translate("pychemqt", "Tª bulbo húmedo, Entalpia")) # QApplication.translate("pychemqt", "Tª bulbo húmedo, Densidad")) # QApplication.translate("pychemqt", "Tª bulbo húmedo, Tª rocio")) # QApplication.translate("pychemqt", "H absoluta, entalpía")) # QApplication.translate("pychemqt", "H relativa, entalpía")) # QApplication.translate("pychemqt", "H absoluta, densidad")) # QApplication.translate("pychemqt", "H relativa, densidad")) # QApplication.translate("pychemqt", "Tª rocio, entalpía")) # QApplication.translate("pychemqt", "Tª rocio, densidad")) def __init__(self, **kwargs): self.kwargs = self.__class__.kwargs.copy() self.__call__(**kwargs) def __call__(self, **kwargs): self.kwargs.update(kwargs) if self.calculable: self.status = 1 self.calculo() logging.debug(QApplication.translate( "pychemqt", "Calculate psychrometric point")) logging.debug(self.kwargs) self.msg = "Solved" @property def calculable(self): tdp = self.kwargs.get("tdp", 0) tdb = self.kwargs.get("tdb", 0) twb = self.kwargs.get("twb", 0) w = self.kwargs.get("w", None) HR = self.kwargs.get("HR", None) # h = self.kwargs.get("h", None) # v = self.kwargs.get("v", 0) self.mode = -1 if tdb and w is not None: self.mode = 0 elif tdb and HR is not None: self.mode = 1 elif tdb and twb: self.mode = 2 elif tdb and tdp: self.mode = 3 elif tdp and HR is not None: self.mode = 4 return bool(self.mode+1) def _P(self): """Barometric pressure calculation, Pa""" if self.kwargs["P"]: P = self.kwargs["P"] elif self.kwargs["z"]: P = _Pbar(self.kwargs["z"]) else: P = 101325. return P def _lib(self): """Properties calculate library, customize in each subclass""" pass def calculo(self): tdp, tdb, twb, P, Pvs, Pv, ws, w, HR, v, h = self._lib() self.tdp = unidades.Temperature(tdp) self.tdb = unidades.Temperature(tdb) self.twb = unidades.Temperature(twb) self.P = unidades.Pressure(P) self.Pvs = unidades.Pressure(Pvs) self.Pv = unidades.Pressure(Pv) self.ws = unidades.Dimensionless(ws, txt="kgw/kgda") self.w = unidades.Dimensionless(w, txt="kgw/kgda") self.HR = unidades.Dimensionless(HR, txt="%") self.mu = unidades.Dimensionless(w/ws*100) self.v = unidades.SpecificVolume(v) self.rho = unidades.Density(1/v) self.h = unidades.Enthalpy(h, "kJkg") self.Xa = 1/(1+self.w/0.62198) self.Xw = 1-self.Xa @classmethod def calculatePlot(cls): """Funtion to calculate point in chart, each child class must define it, as default use ideal gas equation of state""" return PsyIdeal.calculatePlot() @staticmethod def LineList(name, Preferences): """Return a list with the values of isoline name to plot""" if Preferences.getboolean("Psychr", name+"Custom"): t = [] for i in Preferences.get("Psychr", name+'List').split(','): if i: t.append(float(i)) else: start = Preferences.getfloat("Psychr", name+"Start") end = Preferences.getfloat("Psychr", name+"End") step = Preferences.getfloat("Psychr", name+"Step") t = list(arange(start, end, step)) return t
if blend_list and len(blend_list) == 2 and len(blend_list[1])>1: d = {} d["label"] = decode(blend_list[0]) d["ingredients"] = [{"coffee": decode(i[0]), "ratio": i[1]} for i in blend_list[1]] return d else: return None except: return None ################### # coffee and blend stock access and rendering unit_translations_singular = { "bag": QApplication.translate("Plus", "bag",None), "box": QApplication.translate("Plus", "box",None), "barrel": QApplication.translate("Plus", "barrel",None) } unit_translations_plural = { "bag": QApplication.translate("Plus", "bags",None), "box": QApplication.translate("Plus", "boxes",None), "barrel": QApplication.translate("Plus", "barrels",None) } def renderAmount(amount,default_unit = None,target_unit_idx = 0): res = "" # first try to convert to default_unit try: unit_size = int(default_unit["size"])
def u(x): return codecs.unicode_escape_decode(x)[0] else: def u(x): return x platf = str(platform.system()) ####################################################################################### #################### MENU STRINGS #################################################### ####################################################################################### #Fake entries to get translations for the Mac Application Menu _mac_services = QApplication.translate("MAC_APPLICATION_MENU", "Services", None) _mac_hide = QApplication.translate("MAC_APPLICATION_MENU", "Hide {0}", None) _mac_hideothers = QApplication.translate("MAC_APPLICATION_MENU", "Hide Others", None) _mac_showall = QApplication.translate("MAC_APPLICATION_MENU", "Show All", None) _mac_preferences = QApplication.translate("MAC_APPLICATION_MENU", "Preferences...", None) _mac_quit = QApplication.translate("MAC_APPLICATION_MENU", "Quit {0}", None) _mac_about = QApplication.translate("MAC_APPLICATION_MENU", "About {0}", None) #File menu items FILE_MENU = QApplication.translate("Menu", "File", None) if platf != 'Darwin': FILE_MENU = "&" + FILE_MENU FILE_MENU_NEW = QApplication.translate("Menu", "New", None) FILE_MENU_OPEN = QApplication.translate("Menu", "Open...", None)
def content(): strlist = [] helpstr = '' #@UnusedVariable newline = '\n' #@UnusedVariable strlist.append( '<head><style> td, th {border: 1px solid #ddd; padding: 6px;} th {padding-top: 6px;padding-bottom: 6px;text-align: left;background-color: #0C6AA6; color: white;} </style></head> <body>' ) strlist.append("<b>") strlist.append( QApplication.translate('HelpDlg', 'PORTS CONFIGURATION', None)) strlist.append("</b>") tbl_Modbus = prettytable.PrettyTable() tbl_Modbus.field_names = [ QApplication.translate('HelpDlg', 'MODBUS SETTINGS', None) ] tbl_Modbus.add_row([ QApplication.translate( 'HelpDlg', 'The MODBUS serial protocols RTU, ASCII, and Binary is using the specified serial port parameters. The MODBUS IP protocol on TCP and UDP is respecting the host IP and port.', None) ]) tbl_Modbus.add_row([ QApplication.translate( 'HelpDlg', 'The inputs 1+2 configure the MODBUS device, inputs 3+4 configure the MODBUS_34 device and so on.\nInputs with the slave id set to 0 are turned off.', None) ]) tbl_Modbus.add_row([ QApplication.translate( 'HelpDlg', 'Function 1 (Read Coils): registers 0 to 65535 corresponding to numbers 000001 to 065536\nFunction 2 (Read Discrete Inputs): registers 0 to 65535 corresponding to numbers 100001 to 165536\nFunction 3 (Read Multiple Holding Registers): registers 0 to 65535 corresponding to numbers 400001 to 465536\nFunction 4 (Read Input Registers): registers 0 to 65535 corresponding to numbers 300001 to 365536', None) ]) tbl_Modbus.add_row([ QApplication.translate( 'HelpDlg', 'Dividers 1/10 and 1/100 can be set to recreate decimals of floats transported as integers multiplied by 10 or 100. Eg. a value of 145.2 might be transmitted as 1452, which is turned back into 145.2 by the 1/10 divider.', None) ]) tbl_Modbus.add_row([ QApplication.translate( 'HelpDlg', 'Temperature readings are automatically converted based on the specified unit per input channel.', None) ]) tbl_Modbus.add_row([ QApplication.translate( 'HelpDlg', 'If a Float or BCD decoder is set, two succeeding 16bit registers are requested and the received 4 bytes interpreted using the byte and word order as specified by the corresponding flag.', None) ]) tbl_Modbus.add_row([ QApplication.translate( 'HelpDlg', 'The PID Control dialog can operate a connected PID slave using the given PID registers to set the p-i-d parameters and the set value (SV). MODBUS commands can be specified to turn the PID slave on and off from that PID Control dialog. See the help page in the Events Dialog for documentation of available MODBUS write commands.', None) ]) tbl_Modbus.add_row([ QApplication.translate( 'HelpDlg', 'The Scan button opens a simple MODBUS scanner to search for data holding registers in the connected device.', None) ]) tbl_Modbus.add_row([ QApplication.translate( 'HelpDlg', 'Refer to the User Manual of your MODBUS device for information specific to the setup required for your device.', None) ]) strlist.append( tbl_Modbus.get_html_string( attributes={ "width": "100%", "border": "1", "padding": "1", "border-collapse": "collapse" })) strlist.append("</body>") helpstr = "".join(strlist) helpstr = re.sub(r"&", r"&", helpstr) return helpstr
def _translate(context, text, disambig): return QApplication.translate(context, text, disambig)
def connect(self): # if self.master and not self.master.socket: # self.master = None if self.master is None: self.commError = False try: # as in the following the port is None, no port is opened on creation of the (py)serial object if self.type == 1: # Serial ASCII from pymodbus.client.sync import ModbusSerialClient self.master = ModbusSerialClient(method='ascii', port=self.comport, baudrate=self.baudrate, bytesize=self.bytesize, parity=self.parity, stopbits=self.stopbits, retry_on_empty=True, timeout=self.timeout) elif self.type == 2: # Serial Binary from pymodbus.client.sync import ModbusSerialClient self.master = ModbusSerialClient(method='binary', port=self.comport, baudrate=self.baudrate, bytesize=self.bytesize, parity=self.parity, stopbits=self.stopbits, retry_on_empty=True, timeout=self.timeout) elif self.type == 3: # TCP from pymodbus.client.sync import ModbusTcpClient try: self.master = ModbusTcpClient( host=self.host, port=self.port, retry_on_empty=True, retries=1, timeout=0.9, #self.timeout ) self.readRetries = 0 except: self.master = ModbusTcpClient( host=self.host, port=self.port, ) elif self.type == 4: # UDP from pymodbus.client.sync import ModbusUdpClient try: self.master = ModbusUdpClient( host=self.host, port=self.port, retry_on_empty=True, retries=3, timeout=0.7, #self.timeout ) except: # older versions of pymodbus don't support the retries, timeout nor the retry_on_empty arguments self.master = ModbusUdpClient( host=self.host, port=self.port, ) else: # Serial RTU from pymodbus.client.sync import ModbusSerialClient self.master = ModbusSerialClient(method='rtu', port=self.comport, baudrate=self.baudrate, bytesize=self.bytesize, parity=self.parity, stopbits=self.stopbits, retry_on_empty=False, timeout=self.timeout) self.readRetries = 1 self.master.connect() self.adderror( QApplication.translate("Error Message", "Connected via MODBUS", None)) time.sleep(.5) # avoid possible hickups on startup except Exception as ex: _, _, exc_tb = sys.exc_info() self.adderror( (QApplication.translate("Error Message", "Modbus Error:", None) + " connect() {0}").format( str(ex)), exc_tb.tb_lineno)
def __init__(self, parent=None, aw=None): super(SamplingDlg, self).__init__(parent, aw) self.setWindowTitle(QApplication.translate("Message", "Sampling", None)) self.setModal(True) self.org_delay = self.aw.qmc.delay self.org_flagKeepON = self.aw.qmc.flagKeepON self.org_flagOpenCompleted = self.aw.qmc.flagOpenCompleted self.keepOnFlag = QCheckBox( QApplication.translate("Label", "Keep ON", None)) self.keepOnFlag.setFocusPolicy(Qt.NoFocus) self.keepOnFlag.setChecked(bool(self.aw.qmc.flagKeepON)) self.openCompletedFlag = QCheckBox( QApplication.translate("Label", "Open Completed Roast in Viewer", None)) self.openCompletedFlag.setFocusPolicy(Qt.NoFocus) self.openCompletedFlag.setChecked(bool(self.aw.qmc.flagOpenCompleted)) self.interval = QDoubleSpinBox() self.interval.setSingleStep(1) self.interval.setValue(self.aw.qmc.delay / 1000.) self.interval.setRange(self.aw.qmc.min_delay / 1000., 40.) self.interval.setDecimals(1) self.interval.setAlignment(Qt.AlignRight) self.interval.setSuffix("s") intervalLayout = QHBoxLayout() intervalLayout.addStretch() intervalLayout.addWidget(self.interval) intervalLayout.addStretch() # connect the ArtisanDialog standard OK/Cancel buttons self.dialogbuttons.accepted.connect(self.ok) self.dialogbuttons.rejected.connect(self.close) flagGrid = QGridLayout() flagGrid.addWidget(self.keepOnFlag, 0, 0) flagGrid.addWidget(self.openCompletedFlag, 1, 0) flagLayout = QHBoxLayout() flagLayout.addStretch() flagLayout.addLayout(flagGrid) flagLayout.addStretch() buttonsLayout = QHBoxLayout() buttonsLayout.addStretch() buttonsLayout.addWidget(self.dialogbuttons) #incorporate layouts layout = QVBoxLayout() layout.addLayout(intervalLayout) layout.addLayout(flagLayout) layout.addStretch() layout.addLayout(buttonsLayout) self.setLayout(layout) self.dialogbuttons.button(QDialogButtonBox.Ok).setFocus() settings = QSettings() if settings.contains("SamplingPosition"): self.move(settings.value("SamplingPosition")) layout.setSizeConstraint(QLayout.SetFixedSize)
def readSingleRegister(self, slave, register, code=3): # import logging # logging.basicConfig() # log = logging.getLogger() # log.setLevel(logging.DEBUG) r = None try: #### lock shared resources ##### self.COMsemaphore.acquire(1) self.connect() retry = self.readRetries while True: try: if code == 1: res = self.master.read_coils(int(register), 1, unit=int(slave)) elif code == 2: res = self.master.read_discrete_inputs(int(register), 1, unit=int(slave)) elif code == 4: res = self.master.read_input_registers(int(register), 1, unit=int(slave)) else: # code==3 res = self.master.read_holding_registers( int(register), 1, unit=int(slave)) except Exception: res = None if res is None or res.isError(): # requires pymodbus v1.5.1 if retry > 0: retry = retry - 1 time.sleep(0.020) else: raise Exception("Exception response") else: break if code in [1, 2]: if res is not None and res.bits[0]: r = 1 else: r = 0 return r else: decoder = getBinaryPayloadDecoderFromRegisters( res.registers, self.byteorderLittle, self.wordorderLittle) r = decoder.decode_16bit_uint() if self.commError: # we clear the previous error and send a message self.commError = False self.adderror( QApplication.translate("Error Message", "Modbus Communication Resumed", None)) return r except Exception: # as ex: # self.disconnect() # import traceback # traceback.print_exc(file=sys.stdout) # _, _, exc_tb = sys.exc_info() # self.adderror((QApplication.translate("Error Message","Modbus Error:",None) + " readSingleRegister() {0}").format(str(ex)),exc_tb.tb_lineno) self.adderror( QApplication.translate("Error Message", "Modbus Communication Error", None)) self.commError = True finally: if self.COMsemaphore.available() < 1: self.COMsemaphore.release(1) #note: logged chars should be unicode not binary settings = str(self.comport) + "," + str( self.baudrate) + "," + str(self.bytesize) + "," + str( self.parity) + "," + str(self.stopbits) + "," + str( self.timeout) ser_str = "MODBUS readSingleRegister :" + settings + " || Slave = " + str( slave) + " || Register = " + str( register) + " || Code = " + str(code) if r is not None: ser_str = ser_str + " || Rx = " + str(r) self.addserial(ser_str)
def __init__(self, parent=None, email=None, remember_credentials=True): super(Login, self).__init__(parent) self.login = None self.passwd = None self.remember = remember_credentials self.linkRegister = QLabel( '<small><a href="' + config.register_url + '">' + QApplication.translate("Plus", "Register", None) + '</a></small>') self.linkRegister.setOpenExternalLinks(True) self.linkResetPassword = QLabel( '<small><a href="' + config.reset_passwd_url + '">' + QApplication.translate("Plus", "Reset Password", None) + '</a></small>') self.linkResetPassword.setOpenExternalLinks(True) self.textName = QLineEdit(self) self.textName.setPlaceholderText( QApplication.translate("Plus", "Email", None)) if email is not None: self.textName.setText(email) self.textName.textChanged.connect(self.textChanged) self.textPass = QLineEdit(self) self.textPass.setEchoMode(QLineEdit.Password) self.textPass.setPlaceholderText( QApplication.translate("Plus", "Password", None)) self.textPass.textChanged.connect(self.textChanged) self.rememberCheckbox = QCheckBox( QApplication.translate("Plus", "Remember", None)) self.rememberCheckbox.setChecked(self.remember) self.rememberCheckbox.stateChanged.connect(self.rememberCheckChanged) self.dialogbuttons = QDialogButtonBox( QDialogButtonBox.Ok | QDialogButtonBox.Cancel, Qt.Horizontal) aw = config.app_window if aw.locale not in aw.qtbase_locales: self.dialogbuttons.button(QDialogButtonBox.Ok).setText( QApplication.translate("Button", "OK", None)) self.dialogbuttons.button(QDialogButtonBox.Cancel).setText( QApplication.translate("Button", "Cancel", None)) self.dialogbuttons.accepted.connect(self.setCredentials) self.dialogbuttons.rejected.connect(self.reject) self.dialogbuttons.button(QDialogButtonBox.Ok).setEnabled(False) self.dialogbuttons.button(QDialogButtonBox.Cancel).setDefault(True) # add additional CMD-. shortcut to close the dialog self.dialogbuttons.button(QDialogButtonBox.Cancel).setShortcut( QKeySequence("Ctrl+.")) # add additional CMD-W shortcut to close this dialog cancelAction = QAction(self, triggered=lambda _: self.reject()) try: cancelAction.setShortcut(QKeySequence.Cancel) except: pass self.dialogbuttons.button(QDialogButtonBox.Cancel).addActions( [cancelAction]) credentialsLayout = QVBoxLayout(self) credentialsLayout.addWidget(self.textName) credentialsLayout.addWidget(self.textPass) credentialsLayout.addWidget(self.rememberCheckbox) credentialsGroup = QGroupBox() credentialsGroup.setLayout(credentialsLayout) buttonLayout = QHBoxLayout() buttonLayout.addStretch() buttonLayout.addWidget(self.dialogbuttons) buttonLayout.addStretch() linkLayout = QHBoxLayout() linkLayout.addStretch() linkLayout.addWidget(self.linkRegister) linkLayout.addStretch() linkLayout.addWidget(self.linkResetPassword) linkLayout.addStretch() layout = QVBoxLayout(self) layout.addWidget(credentialsGroup) layout.addLayout(linkLayout) layout.addLayout(buttonLayout) layout.setContentsMargins(10, 10, 10, 10) layout.setSpacing(5)
def getalsopath(self, _): filename = self.aw.ArtisanExistingDirectoryDialog( msg=QApplication.translate("Form Caption", "AutoSave Save Also Path", None)) self.pathAlsoEdit.setText(filename)