class UI_reacciones(QtWidgets.QDialog): reaction=reaction.Reaction() def __init__(self, reaccion=None, parent=None): super(UI_reacciones, self).__init__(parent) self.evaluate=Evaluate() self.evaluate.finished.connect(self.rellenar) self.indices, self.nombres, M=getComponents() gridLayout = QtWidgets.QGridLayout(self) lyt=QtWidgets.QHBoxLayout() lyt.addWidget(QtWidgets.QLabel(QtWidgets.QApplication.translate("pychemqt", "Key component"))) self.key=QtWidgets.QComboBox() for i, nombre in enumerate(self.nombres): self.key.addItem("%i - %s" %(i+1, nombre)) self.key.currentIndexChanged.connect(partial(self.changeParams, "key")) lyt.addWidget(self.key) lyt.addItem(QtWidgets.QSpacerItem(10,10,QtWidgets.QSizePolicy.Expanding,QtWidgets.QSizePolicy.Fixed)) gridLayout.addLayout(lyt,1,1,1,5) lyt=QtWidgets.QHBoxLayout() lyt.addWidget(QtWidgets.QLabel(QtWidgets.QApplication.translate("pychemqt", "Phase"))) self.fase=QtWidgets.QComboBox() for txt in reaction.Reaction.TEXT_PHASE: self.fase.addItem(txt) self.fase.currentIndexChanged.connect(partial(self.changeParams, "fase")) lyt.addWidget(self.fase) self.Formula=QtWidgets.QLabel() self.Formula.setAlignment(QtCore.Qt.AlignCenter) self.Formula.setSizePolicy(QtWidgets.QSizePolicy.Expanding,QtWidgets.QSizePolicy.Fixed) lyt.addWidget(self.Formula) gridLayout.addLayout(lyt,2,1,1,5) lyt=QtWidgets.QVBoxLayout() title=self.nombres[:] title.append("") self.Estequiometria=Tabla(1, verticalHeaderLabels=title, horizontalHeader=[QtWidgets.QApplication.translate("pychemqt", "Coefficients")], filas=len(self.indices)) self.Estequiometria.setFixedHeight(22*len(self.indices)+22+4+22) lyt.addWidget(self.Estequiometria) self.Estequiometria.addRow() brush=QtGui.QBrush(QtGui.QColor("#eaeaea")) self.Estequiometria.item(len(self.indices), 0).setBackground(brush) self.Estequiometria.item(len(self.indices), 0).setFlags(QtCore.Qt.NoItemFlags) self.Estequiometria.cellChanged.connect(self.reaccionCambiada) lyt.addItem(QtWidgets.QSpacerItem(10,10,QtWidgets.QSizePolicy.Fixed,QtWidgets.QSizePolicy.Expanding)) gridLayout.addLayout(lyt,3,1,1,2) lyt=QtWidgets.QGridLayout() lyt.addItem(QtWidgets.QSpacerItem(10,10,QtWidgets.QSizePolicy.Fixed,QtWidgets.QSizePolicy.Fixed),1,1) self.formula=QtWidgets.QCheckBox(QtWidgets.QApplication.translate("pychemqt", "Use name in formula")) self.formula.toggled.connect(partial(self.changeParams, "formula")) lyt.addWidget(self.formula,1,2,1,2) self.customHr=QtWidgets.QCheckBox("ΔHr "+QtWidgets.QApplication.translate("pychemqt", "user specified")) self.customHr.toggled.connect(self.changeHr) lyt.addWidget(self.customHr,2,2,1,2) lyt.addWidget(QtWidgets.QLabel("ΔHr<sup>o</sup>"),3,2) self.Hr=Entrada_con_unidades(unidades.MolarEnthalpy, readOnly=True) self.Hr.valueChanged.connect(partial(self.changeParams, "Hr")) lyt.addWidget(self.Hr,3,3) lyt.addItem(QtWidgets.QSpacerItem(10,10,QtWidgets.QSizePolicy.Fixed,QtWidgets.QSizePolicy.Expanding)) gridLayout.addLayout(lyt,3,3,1,2) gridLayout.addItem(QtWidgets.QSpacerItem(10,10,QtWidgets.QSizePolicy.Fixed,QtWidgets.QSizePolicy.Fixed),4,2) lyt=QtWidgets.QHBoxLayout() lyt.addWidget(QtWidgets.QLabel(QtWidgets.QApplication.translate("pychemqt", "Type"))) self.tipo=QtWidgets.QComboBox() for txt in reaction.Reaction.TEXT_TYPE: self.tipo.addItem(txt) self.tipo.currentIndexChanged.connect(partial(self.changeParams, "tipo")) lyt.addWidget(self.tipo) lyt.addItem(QtWidgets.QSpacerItem(20,10,QtWidgets.QSizePolicy.Fixed,QtWidgets.QSizePolicy.Fixed)) lyt.addWidget(QtWidgets.QLabel(QtWidgets.QApplication.translate("pychemqt", "Concentration"))) self.base=QtWidgets.QComboBox() for txt in reaction.Reaction.TEXT_BASE: self.base.addItem(txt) self.base.currentIndexChanged.connect(partial(self.changeParams, "base")) lyt.addWidget(self.base) lyt.addItem(QtWidgets.QSpacerItem(10,10,QtWidgets.QSizePolicy.Expanding,QtWidgets.QSizePolicy.Fixed)) gridLayout.addLayout(lyt,5,1,1,5) self.stacked = QtWidgets.QStackedWidget() self.tipo.currentIndexChanged.connect(self.stacked.setCurrentIndex) gridLayout.addWidget(self.stacked,6,1,1,5) gridLayout.addItem(QtWidgets.QSpacerItem(10,10,QtWidgets.QSizePolicy.Expanding,QtWidgets.QSizePolicy.Expanding),7,1,1,5) widget=QtWidgets.QWidget() self.stacked.addWidget(widget) lyt=QtWidgets.QGridLayout(widget) lyt.addWidget(QtWidgets.QLabel("<h3>"+QtWidgets.QApplication.translate("pychemqt", "Estequiometric reaction")+"</h3>"),1,1,1,4) self.Conversion=Tabla(1, verticalHeaderModel="C", filas=3) self.Conversion.setConnected() self.Conversion.setFixedWidth(100) lyt.addWidget(self.Conversion,2,1,3,1) label=QtWidgets.QLabel() label.setPixmap(QtGui.QPixmap(os.environ["pychemqt"]+"/images/equation/reaction_conversion.png")) lyt.addWidget(label,2,2,1,3) lyt.addWidget(QtWidgets.QLabel(QtWidgets.QApplication.translate("pychemqt", "Temperature unit")),3,2) self.unidadesTemperatura=QtWidgets.QComboBox() for i in unidades.Temperature.__text__: self.unidadesTemperatura.addItem(i) lyt.addWidget(self.unidadesTemperatura,3,3) lyt.addItem(QtWidgets.QSpacerItem(10,10,QtWidgets.QSizePolicy.Expanding,QtWidgets.QSizePolicy.Expanding),4,4) lyt.addItem(QtWidgets.QSpacerItem(10,10,QtWidgets.QSizePolicy.Expanding,QtWidgets.QSizePolicy.Expanding),5,1,1,5) widget=QtWidgets.QWidget() self.stacked.addWidget(widget) lyt=QtWidgets.QGridLayout(widget) self.check_KFijo=QtWidgets.QRadioButton(QtWidgets.QApplication.translate("pychemqt", "Fixed")) self.check_KFijo.toggled.connect(self.KeqChanged) lyt.addWidget(self.check_KFijo,1,1,1,2) lyt.addWidget(QtWidgets.QLabel("K<sub>eq</sub>"),1,3) self.Keq=Entrada_con_unidades(float) lyt.addWidget(self.Keq,1,4) label=QtWidgets.QLabel() label.setPixmap(QtGui.QPixmap(os.environ["pychemqt"]+"/images/equation/reaction_equilibrium.png")) lyt.addWidget(label,1,5,1,4) self.check_KEq=QtWidgets.QRadioButton(QtWidgets.QApplication.translate("pychemqt", "Equation")) self.check_KEq.toggled.connect(self.KeqChanged) lyt.addWidget(self.check_KEq,2,1,1,2) self.check_KTabla=QtWidgets.QRadioButton(QtWidgets.QApplication.translate("pychemqt", "Table")) self.check_KTabla.toggled.connect(self.KeqChanged) lyt.addWidget(self.check_KTabla,2,5,1,2) self.KEq_Dat=Tabla(1, verticalHeaderLabels=["A", "B", "C", "D", "E", "F", "G", "H"], filas=8) self.KEq_Dat.setFixedHeight(22*8+4) self.KEq_Dat.setFixedWidth(120) lyt.addWidget(self.KEq_Dat,3,3,1,2) self.KEq_Tab=Tabla(4, horizontalHeader=["T, K", "Keq", "Kcalc", "%Error"], verticalHeader=False, columnReadOnly=[False, False, True, True]) self.KEq_Tab.setSizePolicy(QtWidgets.QSizePolicy.Expanding,QtWidgets.QSizePolicy.Expanding) self.KEq_Tab.setFixedWidth(400) self.KEq_Tab.setConnected() self.KEq_Tab.rowFinished.connect(self.Regresion) self.KEq_Tab.setAlternatingRowColors(False) lyt.addWidget(self.KEq_Tab,3,5,1,4) lyt.addWidget(QtWidgets.QLabel("r²"),4,5) self.r2=Entrada_con_unidades(float, readOnly=True) lyt.addWidget(self.r2,4,6) self.botonTablaPlot=QtWidgets.QPushButton(QtGui.QIcon(QtGui.QPixmap(os.environ["pychemqt"]+"/images/button/plot.png")), QtWidgets.QApplication.translate("pychemqt", "Plot")) self.botonTablaPlot.clicked.connect(self.Plot) lyt.addWidget(self.botonTablaPlot,4,7) self.botonTablaClear=QtWidgets.QPushButton(QtGui.QIcon(QtGui.QPixmap(os.environ["pychemqt"]+"/images/button/clear.png")), QtWidgets.QApplication.translate("pychemqt", "Clear")) self.botonTablaClear.clicked.connect(self.KEq_Tab.clear) lyt.addWidget(self.botonTablaClear,4,8) label=QtWidgets.QLabel() label.setPixmap(QtGui.QPixmap(os.environ["pychemqt"]+"/images/equation/reaction_equilibrium2.png")) label.setAlignment(QtCore.Qt.AlignCenter) lyt.addWidget(label,5,1,1,8) self.checkGibbs=QtWidgets.QRadioButton(QtWidgets.QApplication.translate("pychemqt", "From Gibbs free energy minimization")) lyt.addWidget(self.checkGibbs,6,1,1,4) self.check_KFijo.setChecked(True) widget=QtWidgets.QWidget() self.stacked.addWidget(widget) lyt=QtWidgets.QGridLayout(widget) widget=QtWidgets.QWidget() self.stacked.addWidget(widget) lyt=QtWidgets.QGridLayout(widget) self.status=Status() gridLayout.addWidget(self.status, 10,1) self.buttonBox = QtWidgets.QDialogButtonBox(QtWidgets.QDialogButtonBox.Cancel|QtWidgets.QDialogButtonBox.Ok) self.buttonBox.accepted.connect(self.accept) self.buttonBox.rejected.connect(self.reject) gridLayout.addWidget(self.buttonBox,10,2,1,4) if reaccion: self.setReaction(reaccion) def changeParams(self, parametro, valor): self.calculo(**{parametro: valor}) def calculo(self, **kwargs): self.status.setState(4) self.evaluate.start(self.reaction, kwargs) def changeHr(self, bool): self.Hr.setReadOnly(not bool) self.changeParams("customHr", bool) def reaccionCambiada(self): kwargs={"componentes": self.indices, "coeficientes": self.Estequiometria.getColumn(0)[:-1]} self.calculo(**kwargs) def setReaction(self, reaction): self.reaction=reaction self.rellenar() # if self.Estequiometria.getValue(0, self.Base.currentIndex()): # reaccion=reaction.Reaction(self.indices, self.Estequiometria.getColumn(0), base=self.Base.currentIndex(), estequiometria=[0, 0, 0.5], formulas=self.checkFormula.isChecked(), calor=self.checkCalorEspecificado.isChecked(), Hr=self.Hr.value, tipo=self.tipo.currentIndex(), conversion=self.Conversion.getColumn(0)[-1::-1]) # self.Balance.setValue(reaccion.error) # if reaccion.state: # self.Formula.setText(reaccion._txt(self.checkFormula.isChecked())) # self.Hr.setValue(reaccion.Hr) # else: # self.Formula.clear() # self.Hr.clear() # self.botonAdd.setEnabled(reaccion.state and not self.botonEdit.isChecked()) # self.reaccion=reaccion def rellenar(self): self.blockSignals(True) for variable in self.reaction.kwargsValue: self.__getattribute__(variable).setValue(self.reaction.kwargs[variable]) for combo in self.reaction.kwargsList: self.__getattribute__(combo).setCurrentIndex(self.reaction.kwargs[combo]) for check in self.reaction.kwargsCheck: self.__getattribute__(check).setChecked(self.reaction.kwargs[check]) self.Estequiometria.setColumn(0, self.reaction.kwargs["coeficientes"]) # self.Conversion.setColumn(0, self.reaction.estequiometria[-1::-1]) self.blockSignals(False) self.status.setState(self.reaction.status, self.reaction.msg) self.Estequiometria.item(len(self.indices), 0).setText(str(self.reaction.error)) if self.reaction.status: self.Formula.setText(self.reaction._txt()) self.Hr.setValue(self.reaction.Hr) def KeqChanged(self): self.Keq.setReadOnly(not self.check_KFijo.isChecked()) self.KEq_Dat.setEnabled(self.check_KEq.isChecked()) self.KEq_Tab.setEnabled(self.check_KTabla.isChecked()) self.botonTablaClear.setEnabled(self.check_KTabla.isChecked()) self.botonTablaPlot.setEnabled(self.check_KTabla.isChecked()) def Regresion(self): t=array(self.KEq_Tab.getColumn(0)[:-1]) k=array(self.KEq_Tab.getColumn(1)[:-1]) if len(t)>=4: if 4<=len(t)<8: inicio=r_[0, 0, 0, 0] f=lambda par, T: exp(par[0]+par[1]/T+par[2]*log(T)+par[3]*T) resto=lambda par, T, k: k-f(par, T) else: inicio=r_[0, 0, 0, 0, 0, 0, 0, 0] f=lambda par, T: exp(par[0]+par[1]/T+par[2]*log(T)+par[3]*T+par[4]*T**2+par[5]*T**3+par[6]*T**4+par[7]*T**5) resto=lambda par, T, k: k-f(par, T) ajuste=leastsq(resto,inicio,args=(t, k)) kcalc=f(ajuste[0], t) error=(k-kcalc)/k*100 self.KEq_Dat.setColumn(0, ajuste[0]) self.KEq_Tab.setColumn(2, kcalc) self.KEq_Tab.setColumn(3, error) if ajuste[1] in [1, 2, 3, 4]: self.ajuste=ajuste[0] def Plot(self): if self.ajuste!=None: t=array(self.KEq_Tab.getColumn(0)[:-1]) k=array(self.KEq_Tab.getColumn(1)[:-1]) if 4<=len(t)<8: f=lambda par, T: exp(par[0]+par[1]/T+par[2]*log(T)+par[3]*T) else: f=lambda par, T: exp(par[0]+par[1]/T+par[2]*log(T)+par[3]*T+par[4]*T**2+par[5]*T**3+par[6]*T**4+par[7]*T**5) grafico=plot.Plot() grafico.data(t, k, 'ro', t, f(self.ajuste, t)) grafico.exec_()
class Entrada_Datos(QtWidgets.QDialog): """Table data input dialog""" def __init__(self, data=None, t=[], property=[], horizontalHeader=[], title="", help=False, helpFile="", DIPPR=False, tc=0, tcValue=None, eq=1, parent=None): """ title: window title data: mrray with original data t: values for x column, generally temperature property: values for 2...n columns horizontalHeader: List with column title help: boolean to show help button helpFile: Path for help file, file or url DIPPR: boolean to show DIPPR widget tc: boolean to show critical temperature (same DIPPR eq need it) tcValue: value for critical temperature eq: Value for DIPPR equation """ super(Entrada_Datos, self).__init__(parent) self.setWindowTitle(title) self.columnas = len(horizontalHeader) self.horizontalHeader = horizontalHeader self.title = title self.helpFile = helpFile gridLayout = QtWidgets.QGridLayout(self) self.botonAbrir = QtWidgets.QPushButton( QtGui.QIcon( QtGui.QPixmap(os.environ["pychemqt"] + "/images/button/fileOpen.png")), QtWidgets.QApplication.translate("pychemqt", "Open")) self.botonAbrir.clicked.connect(self.Abrir) gridLayout.addWidget(self.botonAbrir, 1, 1) self.botonGuardar = QtWidgets.QPushButton( QtGui.QIcon( QtGui.QPixmap(os.environ["pychemqt"] + "/images/button/fileSave.png")), QtWidgets.QApplication.translate("pychemqt", "Save")) self.botonGuardar.clicked.connect(self.Guardar) gridLayout.addWidget(self.botonGuardar, 1, 2) self.botonDelete = QtWidgets.QPushButton( QtGui.QIcon( QtGui.QPixmap(os.environ["pychemqt"] + "/images/button/clear.png")), QtWidgets.QApplication.translate("pychemqt", "Clear")) self.botonDelete.clicked.connect(self.Borrar) gridLayout.addWidget(self.botonDelete, 1, 3) gridLayout.addItem( QtWidgets.QSpacerItem(0, 0, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Expanding), 1, 4) self.tabla = Tabla(self.columnas, horizontalHeader=horizontalHeader, verticalHeader=False, stretch=False) self.tabla.setConnected() if data: self.tabla.setData(data) self.tabla.addRow() elif t and property: self.tabla.setColumn(0, t) self.tabla.setColumn(1, property) gridLayout.addWidget(self.tabla, 2, 1, 1, 4) if DIPPR: self.eqDIPPR = eqDIPPR(eq) gridLayout.addWidget(self.eqDIPPR, 3, 1, 1, 4) self.eqDIPPR.eqDIPPR.valueChanged.connect(self.showTc) if tc: lyt = QtWidgets.QHBoxLayout() self.labelTc = QtWidgets.QLabel("Tc: ", self) lyt.addWidget(self.labelTc) self.tc = Entrada_con_unidades(Temperature, value=tcValue) lyt.addWidget(self.tc) lyt.addItem( QtWidgets.QSpacerItem(0, 0, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Expanding)) gridLayout.addItem(lyt, 4, 1, 1, 4) self.showTc(1) if help: botones = QtWidgets.QDialogButtonBox.Help | \ QtWidgets.QDialogButtonBox.Cancel | \ QtWidgets.QDialogButtonBox.Ok else: botones = QtWidgets.QDialogButtonBox.Cancel | \ QtWidgets.QDialogButtonBox.Ok self.boton = QtWidgets.QDialogButtonBox(botones) self.boton.accepted.connect(self.accept) self.boton.rejected.connect(self.reject) self.boton.helpRequested.connect(self.ayuda) gridLayout.addWidget(self.boton, 5, 1, 1, 4) def showTc(self, value): self.labelTc.setVisible(value in (7, 9)) self.tc.setVisible(value in (7, 9)) def Abrir(self): fname = QtWidgets.QFileDialog.getOpenFileName( self, QtWidgets.QApplication.translate("pychemqt", "Open text file"), "./") if fname: data = loadtxt(fname) self.tabla.setData(data) self.tabla.addRow() def Guardar(self): fname = QtWidgets.QFileDialog.getSaveFileName( self, QtWidgets.QApplication.translate("pychemqt", "Save data to file"), "./") if fname: with open(fname, 'w') as file: file.write("#" + self.title + "\n") file.write("#") try: for i in self.horizontalHeader: file.write(i + "\t") except UnicodeEncodeError: pass file.write("\n") data = self.data for fila in range(len(data)): for columna in range(self.tabla.columnCount()): file.write(str(data[fila][columna]) + "\t") file.write("\n") def Borrar(self): """Clear table""" self.tabla.setRowCount(1) self.tabla.clearContents() def ayuda(self): """Show help file""" url = QtCore.QUrl(self.helpFile) QtGui.QDesktopServices.openUrl(url) @property def data(self): return self.tabla.getData()
class UI_reacciones(QtWidgets.QDialog): reaction = reaction.Reaction() def __init__(self, reaccion=None, parent=None): super(UI_reacciones, self).__init__(parent) self.evaluate = Evaluate() self.evaluate.finished.connect(self.rellenar) self.indices, self.nombres, M = getComponents() gridLayout = QtWidgets.QGridLayout(self) lyt = QtWidgets.QHBoxLayout() lyt.addWidget( QtWidgets.QLabel( QtWidgets.QApplication.translate("pychemqt", "Key component"))) self.key = QtWidgets.QComboBox() for i, nombre in enumerate(self.nombres): self.key.addItem("%i - %s" % (i + 1, nombre)) self.key.currentIndexChanged.connect(partial(self.changeParams, "key")) lyt.addWidget(self.key) lyt.addItem( QtWidgets.QSpacerItem(10, 10, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Fixed)) gridLayout.addLayout(lyt, 1, 1, 1, 5) lyt = QtWidgets.QHBoxLayout() lyt.addWidget( QtWidgets.QLabel( QtWidgets.QApplication.translate("pychemqt", "Phase"))) self.fase = QtWidgets.QComboBox() for txt in reaction.Reaction.TEXT_PHASE: self.fase.addItem(txt) self.fase.currentIndexChanged.connect( partial(self.changeParams, "fase")) lyt.addWidget(self.fase) self.Formula = QtWidgets.QLabel() self.Formula.setAlignment(QtCore.Qt.AlignCenter) self.Formula.setSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Fixed) lyt.addWidget(self.Formula) gridLayout.addLayout(lyt, 2, 1, 1, 5) lyt = QtWidgets.QVBoxLayout() title = self.nombres[:] title.append("") self.Estequiometria = Tabla(1, verticalHeaderLabels=title, horizontalHeader=[ QtWidgets.QApplication.translate( "pychemqt", "Coefficients") ], filas=len(self.indices)) self.Estequiometria.setFixedHeight(22 * len(self.indices) + 22 + 4 + 22) lyt.addWidget(self.Estequiometria) self.Estequiometria.addRow() brush = QtGui.QBrush(QtGui.QColor("#eaeaea")) self.Estequiometria.item(len(self.indices), 0).setBackground(brush) self.Estequiometria.item(len(self.indices), 0).setFlags(QtCore.Qt.NoItemFlags) self.Estequiometria.cellChanged.connect(self.reaccionCambiada) lyt.addItem( QtWidgets.QSpacerItem(10, 10, QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Expanding)) gridLayout.addLayout(lyt, 3, 1, 1, 2) lyt = QtWidgets.QGridLayout() lyt.addItem( QtWidgets.QSpacerItem(10, 10, QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Fixed), 1, 1) self.formula = QtWidgets.QCheckBox( QtWidgets.QApplication.translate("pychemqt", "Use name in formula")) self.formula.toggled.connect(partial(self.changeParams, "formula")) lyt.addWidget(self.formula, 1, 2, 1, 2) self.customHr = QtWidgets.QCheckBox( "ΔHr " + QtWidgets.QApplication.translate("pychemqt", "user specified")) self.customHr.toggled.connect(self.changeHr) lyt.addWidget(self.customHr, 2, 2, 1, 2) lyt.addWidget(QtWidgets.QLabel("ΔHr<sup>o</sup>"), 3, 2) self.Hr = Entrada_con_unidades(unidades.MolarEnthalpy, readOnly=True) self.Hr.valueChanged.connect(partial(self.changeParams, "Hr")) lyt.addWidget(self.Hr, 3, 3) lyt.addItem( QtWidgets.QSpacerItem(10, 10, QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Expanding)) gridLayout.addLayout(lyt, 3, 3, 1, 2) gridLayout.addItem( QtWidgets.QSpacerItem(10, 10, QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Fixed), 4, 2) lyt = QtWidgets.QHBoxLayout() lyt.addWidget( QtWidgets.QLabel( QtWidgets.QApplication.translate("pychemqt", "Type"))) self.tipo = QtWidgets.QComboBox() for txt in reaction.Reaction.TEXT_TYPE: self.tipo.addItem(txt) self.tipo.currentIndexChanged.connect( partial(self.changeParams, "tipo")) lyt.addWidget(self.tipo) lyt.addItem( QtWidgets.QSpacerItem(20, 10, QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Fixed)) lyt.addWidget( QtWidgets.QLabel( QtWidgets.QApplication.translate("pychemqt", "Concentration"))) self.base = QtWidgets.QComboBox() for txt in reaction.Reaction.TEXT_BASE: self.base.addItem(txt) self.base.currentIndexChanged.connect( partial(self.changeParams, "base")) lyt.addWidget(self.base) lyt.addItem( QtWidgets.QSpacerItem(10, 10, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Fixed)) gridLayout.addLayout(lyt, 5, 1, 1, 5) self.stacked = QtWidgets.QStackedWidget() self.tipo.currentIndexChanged.connect(self.stacked.setCurrentIndex) gridLayout.addWidget(self.stacked, 6, 1, 1, 5) gridLayout.addItem( QtWidgets.QSpacerItem(10, 10, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Expanding), 7, 1, 1, 5) widget = QtWidgets.QWidget() self.stacked.addWidget(widget) lyt = QtWidgets.QGridLayout(widget) lyt.addWidget( QtWidgets.QLabel("<h3>" + QtWidgets.QApplication.translate( "pychemqt", "Estequiometric reaction") + "</h3>"), 1, 1, 1, 4) self.Conversion = Tabla(1, verticalHeaderModel="C", filas=3) self.Conversion.setConnected() self.Conversion.setFixedWidth(100) lyt.addWidget(self.Conversion, 2, 1, 3, 1) label = QtWidgets.QLabel() label.setPixmap( QtGui.QPixmap(os.environ["pychemqt"] + "/images/equation/reaction_conversion.png")) lyt.addWidget(label, 2, 2, 1, 3) lyt.addWidget( QtWidgets.QLabel( QtWidgets.QApplication.translate("pychemqt", "Temperature unit")), 3, 2) self.unidadesTemperatura = QtWidgets.QComboBox() for i in unidades.Temperature.__text__: self.unidadesTemperatura.addItem(i) lyt.addWidget(self.unidadesTemperatura, 3, 3) lyt.addItem( QtWidgets.QSpacerItem(10, 10, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Expanding), 4, 4) lyt.addItem( QtWidgets.QSpacerItem(10, 10, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Expanding), 5, 1, 1, 5) widget = QtWidgets.QWidget() self.stacked.addWidget(widget) lyt = QtWidgets.QGridLayout(widget) self.check_KFijo = QtWidgets.QRadioButton( QtWidgets.QApplication.translate("pychemqt", "Fixed")) self.check_KFijo.toggled.connect(self.KeqChanged) lyt.addWidget(self.check_KFijo, 1, 1, 1, 2) lyt.addWidget(QtWidgets.QLabel("K<sub>eq</sub>"), 1, 3) self.Keq = Entrada_con_unidades(float) lyt.addWidget(self.Keq, 1, 4) label = QtWidgets.QLabel() label.setPixmap( QtGui.QPixmap(os.environ["pychemqt"] + "/images/equation/reaction_equilibrium.png")) lyt.addWidget(label, 1, 5, 1, 4) self.check_KEq = QtWidgets.QRadioButton( QtWidgets.QApplication.translate("pychemqt", "Equation")) self.check_KEq.toggled.connect(self.KeqChanged) lyt.addWidget(self.check_KEq, 2, 1, 1, 2) self.check_KTabla = QtWidgets.QRadioButton( QtWidgets.QApplication.translate("pychemqt", "Table")) self.check_KTabla.toggled.connect(self.KeqChanged) lyt.addWidget(self.check_KTabla, 2, 5, 1, 2) self.KEq_Dat = Tabla( 1, verticalHeaderLabels=["A", "B", "C", "D", "E", "F", "G", "H"], filas=8) self.KEq_Dat.setFixedHeight(22 * 8 + 4) self.KEq_Dat.setFixedWidth(120) lyt.addWidget(self.KEq_Dat, 3, 3, 1, 2) self.KEq_Tab = Tabla( 4, horizontalHeader=["T, K", "Keq", "Kcalc", "%Error"], verticalHeader=False, columnReadOnly=[False, False, True, True]) self.KEq_Tab.setSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Expanding) self.KEq_Tab.setFixedWidth(400) self.KEq_Tab.setConnected() self.KEq_Tab.rowFinished.connect(self.Regresion) self.KEq_Tab.setAlternatingRowColors(False) lyt.addWidget(self.KEq_Tab, 3, 5, 1, 4) lyt.addWidget(QtWidgets.QLabel("r²"), 4, 5) self.r2 = Entrada_con_unidades(float, readOnly=True) lyt.addWidget(self.r2, 4, 6) self.botonTablaPlot = QtWidgets.QPushButton( QtGui.QIcon( QtGui.QPixmap(os.environ["pychemqt"] + "/images/button/plot.png")), QtWidgets.QApplication.translate("pychemqt", "Plot")) self.botonTablaPlot.clicked.connect(self.Plot) lyt.addWidget(self.botonTablaPlot, 4, 7) self.botonTablaClear = QtWidgets.QPushButton( QtGui.QIcon( QtGui.QPixmap(os.environ["pychemqt"] + "/images/button/clear.png")), QtWidgets.QApplication.translate("pychemqt", "Clear")) self.botonTablaClear.clicked.connect(self.KEq_Tab.clear) lyt.addWidget(self.botonTablaClear, 4, 8) label = QtWidgets.QLabel() label.setPixmap( QtGui.QPixmap(os.environ["pychemqt"] + "/images/equation/reaction_equilibrium2.png")) label.setAlignment(QtCore.Qt.AlignCenter) lyt.addWidget(label, 5, 1, 1, 8) self.checkGibbs = QtWidgets.QRadioButton( QtWidgets.QApplication.translate( "pychemqt", "From Gibbs free energy minimization")) lyt.addWidget(self.checkGibbs, 6, 1, 1, 4) self.check_KFijo.setChecked(True) widget = QtWidgets.QWidget() self.stacked.addWidget(widget) lyt = QtWidgets.QGridLayout(widget) widget = QtWidgets.QWidget() self.stacked.addWidget(widget) lyt = QtWidgets.QGridLayout(widget) self.status = Status() gridLayout.addWidget(self.status, 10, 1) self.buttonBox = QtWidgets.QDialogButtonBox( QtWidgets.QDialogButtonBox.Cancel | QtWidgets.QDialogButtonBox.Ok) self.buttonBox.accepted.connect(self.accept) self.buttonBox.rejected.connect(self.reject) gridLayout.addWidget(self.buttonBox, 10, 2, 1, 4) if reaccion: self.setReaction(reaccion) def changeParams(self, parametro, valor): self.calculo(**{parametro: valor}) def calculo(self, **kwargs): self.status.setState(4) self.evaluate.start(self.reaction, kwargs) def changeHr(self, bool): self.Hr.setReadOnly(not bool) self.changeParams("customHr", bool) def reaccionCambiada(self): kwargs = { "componentes": self.indices, "coeficientes": self.Estequiometria.getColumn(0)[:-1] } self.calculo(**kwargs) def setReaction(self, reaction): self.reaction = reaction self.rellenar() # if self.Estequiometria.getValue(0, self.Base.currentIndex()): # reaccion=reaction.Reaction(self.indices, self.Estequiometria.getColumn(0), base=self.Base.currentIndex(), estequiometria=[0, 0, 0.5], formulas=self.checkFormula.isChecked(), calor=self.checkCalorEspecificado.isChecked(), Hr=self.Hr.value, tipo=self.tipo.currentIndex(), conversion=self.Conversion.getColumn(0)[-1::-1]) # self.Balance.setValue(reaccion.error) # if reaccion.state: # self.Formula.setText(reaccion._txt(self.checkFormula.isChecked())) # self.Hr.setValue(reaccion.Hr) # else: # self.Formula.clear() # self.Hr.clear() # self.botonAdd.setEnabled(reaccion.state and not self.botonEdit.isChecked()) # self.reaccion=reaccion def rellenar(self): self.blockSignals(True) for variable in self.reaction.kwargsValue: self.__getattribute__(variable).setValue( self.reaction.kwargs[variable]) for combo in self.reaction.kwargsList: self.__getattribute__(combo).setCurrentIndex( self.reaction.kwargs[combo]) for check in self.reaction.kwargsCheck: self.__getattribute__(check).setChecked( self.reaction.kwargs[check]) self.Estequiometria.setColumn(0, self.reaction.kwargs["coeficientes"]) # self.Conversion.setColumn(0, self.reaction.estequiometria[-1::-1]) self.blockSignals(False) self.status.setState(self.reaction.status, self.reaction.msg) self.Estequiometria.item(len(self.indices), 0).setText(str(self.reaction.error)) if self.reaction.status: self.Formula.setText(self.reaction._txt()) self.Hr.setValue(self.reaction.Hr) def KeqChanged(self): self.Keq.setReadOnly(not self.check_KFijo.isChecked()) self.KEq_Dat.setEnabled(self.check_KEq.isChecked()) self.KEq_Tab.setEnabled(self.check_KTabla.isChecked()) self.botonTablaClear.setEnabled(self.check_KTabla.isChecked()) self.botonTablaPlot.setEnabled(self.check_KTabla.isChecked()) def Regresion(self): t = array(self.KEq_Tab.getColumn(0)[:-1]) k = array(self.KEq_Tab.getColumn(1)[:-1]) if len(t) >= 4: if 4 <= len(t) < 8: inicio = r_[0, 0, 0, 0] f = lambda par, T: exp(par[0] + par[1] / T + par[2] * log(T) + par[3] * T) resto = lambda par, T, k: k - f(par, T) else: inicio = r_[0, 0, 0, 0, 0, 0, 0, 0] f = lambda par, T: exp(par[0] + par[1] / T + par[2] * log( T) + par[3] * T + par[4] * T**2 + par[5] * T**3 + par[6] * T**4 + par[7] * T**5) resto = lambda par, T, k: k - f(par, T) ajuste = leastsq(resto, inicio, args=(t, k)) kcalc = f(ajuste[0], t) error = (k - kcalc) / k * 100 self.KEq_Dat.setColumn(0, ajuste[0]) self.KEq_Tab.setColumn(2, kcalc) self.KEq_Tab.setColumn(3, error) if ajuste[1] in [1, 2, 3, 4]: self.ajuste = ajuste[0] def Plot(self): if self.ajuste != None: t = array(self.KEq_Tab.getColumn(0)[:-1]) k = array(self.KEq_Tab.getColumn(1)[:-1]) if 4 <= len(t) < 8: f = lambda par, T: exp(par[0] + par[1] / T + par[2] * log(T) + par[3] * T) else: f = lambda par, T: exp(par[0] + par[1] / T + par[2] * log( T) + par[3] * T + par[4] * T**2 + par[5] * T**3 + par[6] * T**4 + par[7] * T**5) grafico = plot.Plot() grafico.data(t, k, 'ro', t, f(self.ajuste, t)) grafico.exec_()
class InputTableWidget(QtWidgets.QWidget): """Table data input dialog""" def __init__(self, columnas, data=None, t=[], property=[], horizontalHeader=[], title="", DIPPR=False, hasTc=0, Tc=None, eq=1, unit=[], parent=None): """ data: mrray with original data t: values for x column, generally temperature property: values for 2...n columns horizontalHeader: List with column title DIPPR: boolean to show DIPPR widget hasTc: boolean to show critical temperature (some DIPPR eq need it) Tc: value for critical temperature eq: Value for DIPPR equation unit: List of unidades classes for column definition """ super(InputTableWidget, self).__init__(parent) self.columnas = columnas self.title = title self.unit = unit gridLayout = QtWidgets.QGridLayout(self) gridLayout.setContentsMargins(0, 0, 0, 0) openButton = QtWidgets.QPushButton(QtGui.QIcon(QtGui.QPixmap( os.environ["pychemqt"]+"/images/button/fileOpen.png")), "") openButton.setToolTip(QtWidgets.QApplication.translate( "pychemqt", "Load data from a file")) openButton.clicked.connect(self.open) gridLayout.addWidget(openButton, 1, 1) saveButton = QtWidgets.QPushButton(QtGui.QIcon(QtGui.QPixmap( os.environ["pychemqt"]+"/images/button/fileSave.png")), "") saveButton.setToolTip(QtWidgets.QApplication.translate( "pychemqt", "Save data to a file")) saveButton.clicked.connect(self.save) gridLayout.addWidget(saveButton, 1, 2) clearButton = QtWidgets.QPushButton(QtGui.QIcon(QtGui.QPixmap( os.environ["pychemqt"]+"/images/button/clear.png")), "") clearButton.setToolTip(QtWidgets.QApplication.translate( "pychemqt", "Clear data")) clearButton.clicked.connect(self.delete) gridLayout.addWidget(clearButton, 1, 3) gridLayout.addItem(QtWidgets.QSpacerItem( 0, 0, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Fixed), 1, 4) self.tabla = Tabla(self.columnas, horizontalHeader=horizontalHeader, verticalHeader=False, stretch=False) self.tabla.setConnected() if unit: hHeader = [] for unit, title in zip(self.unit, horizontalHeader): hHeader.append("%s, %s" % (title, unit.text())) self.tabla.setHorizontalHeaderLabels(hHeader) self.tabla.horizontalHeader().sectionClicked.connect(self.editUnit) if data: self.tabla.setData(data) self.tabla.addRow() elif t and property: self.tabla.setColumn(0, t) self.tabla.setColumn(1, property) gridLayout.addWidget(self.tabla, 2, 1, 1, 4) if DIPPR: self.eqDIPPR = eqDIPPR(eq) gridLayout.addWidget(self.eqDIPPR, 3, 1, 1, 4) self.eqDIPPR.eqDIPPR.valueChanged.connect(self.showTc) self.labelTc = QtWidgets.QLabel("Tc: ", self) gridLayout.addWidget(self.labelTc, 4, 1) self.tc = Entrada_con_unidades(Temperature, value=Tc) gridLayout.addWidget(self.tc, 4, 2, 1, 3) self.showTc(1) def showTc(self, value): """Show/hide Tc widget""" self.labelTc.setVisible(value in (7, 9)) self.tc.setVisible(value in (7, 9)) def open(self): """Load data from a test file""" fname, ext = QtWidgets.QFileDialog.getOpenFileName( self, QtWidgets.QApplication.translate("pychemqt", "Open text file"), "./") if fname: try: # Numpy raise error if use the fname directly and find a # non-latin1 character, inclusive in comment lines with open(fname, "rb") as file: data = loadtxt(file) self.delete() self.tabla.setData(data) except ValueError as er: # Raise a error msg if the file can load by loadtxt, the user # can select any type of file and the input error is possible title = QtWidgets.QApplication.translate( "pychemqt", "Failed to load file") msg = fname + "\n" + er.args[0] QtWidgets.QMessageBox.critical(self, title, msg) def save(self): """Save currend data of table to a file""" fname, ext = QtWidgets.QFileDialog.getSaveFileName( self, QtWidgets.QApplication.translate("pychemqt", "Save data to file"), "./") if fname: with open(fname, 'w') as file: file.write("#"+self.title+"\n") file.write("#") for i in range(self.tabla.columnCount()): item = self.tabla.horizontalHeaderItem(i) file.write(item.text()+"\t") file.write("\n") data = self.data for fila in range(len(data)): for columna in range(self.tabla.columnCount()): file.write(str(data[fila][columna])+"\t") file.write("\n") def delete(self): """Clear table""" self.tabla.setRowCount(0) self.tabla.clearContents() self.tabla.addRow() @property def data(self): return self.tabla.getData() def column(self, column, magnitud=None, unit="conf"): """ column: column to get magnitud: magnitud to get the values unit: unit of the values in table""" data = self.tabla.getColumn(column) if self.unit: magnitud = self.unit[column] tx = self.tabla.horizontalHeaderItem(column).text().split(", ")[-1] unit = magnitud.__units__[magnitud.__text__.index(tx)] if magnitud is not None: data = [magnitud(x, unit) for x in data] return data def editUnit(self, col): """Show dialog to config input unit""" unit = self.unit[col] widget = QtWidgets.QComboBox(self.tabla) for txt in unit.__text__: widget.addItem(txt) txt = self.tabla.horizontalHeaderItem(col).text().split(", ")[-1] widget.setCurrentText(txt) # Define Unit combobox geometry size = self.tabla.horizontalHeader().sectionSize(col) pos = self.tabla.horizontalHeader().sectionPosition(col) h = self.tabla.horizontalHeader().height() geometry = QtCore.QRect(pos, 0, size, h) widget.setGeometry(geometry) widget.currentIndexChanged["int"].connect( partial(self.updateHeader, col)) widget.show() widget.showPopup() def updateHeader(self, col, index): """Change the text in header""" widget = self.sender() txt = self.tabla.horizontalHeaderItem(col).text() newtxt = "%s, %s" % (txt.split(",")[0], widget.currentText()) self.tabla.setHorizontalHeaderItem( col, QtWidgets.QTableWidgetItem(newtxt)) widget.close()