#!/usr/bin/python3
# -*- coding: utf-8 -*-
'''Pychemqt, Chemical Engineering Process simulator
Copyright (C) 2009-2025, Juan José Gómez Romera <jjgomera@gmail.com>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
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/>.
.. include:: qtelemental.rst
The module include all related functionality
* :class:`qtelemental`: Periodic table dialog
* :class:`boton`: Element button in periodic table
* :class:`ElementDialog`: Dialog to show properties of components
and its configuration
* :class:`Config`: Configuration widget
* :class:`ConfigDialog`: Dialog tool for standalone use
'''
from configparser import ConfigParser
import logging
import os
from tools.qt import QtCore, QtGui, QtWidgets
from UI.widgets import Entrada_con_unidades, Tabla
from lib import unidades
from lib.elemental import Elemental, _configValues, cleanFloat
from lib.config import conf_dir
font7 = QtGui.QFont()
font7.setPointSizeF(7.6)
font11 = QtGui.QFont()
font11.setPointSize(11)
font20 = QtGui.QFont()
font20.setPointSize(20)
font_title = QtGui.QFont()
font_title.setWeight(75)
font_title.setPointSize(11)
font_title.setBold(True)
palette = QtGui.QPalette()
palette.setColor(QtGui.QPalette.ColorRole.Window, QtGui.QColor("#c8c8c8"))
alignment = QtCore.Qt.AlignmentFlag.AlignTrailing | \
QtCore.Qt.AlignmentFlag.AlignRight | QtCore.Qt.AlignmentFlag.AlignVCenter
[docs]
class qtelemental(QtWidgets.QDialog):
"""Periodic table graph"""
[docs]
def __init__(self, parent=None):
super().__init__(parent)
self.__TEXTSTATUS__ = self.tr("Launched periodic table aplication")
self.setWindowIcon(QtGui.QIcon(QtGui.QPixmap(
os.environ["pychemqt"]+"/images/button/PeriodicTableIcon.png")))
self.setWindowTitle(self.tr("Periodic Table"))
self.Preferences = ConfigParser()
self.Preferences.read(conf_dir+"pychemqtrc")
layout = QtWidgets.QGridLayout(self)
layout.setSpacing(2)
self.populate()
layout.addItem(QtWidgets.QSpacerItem(
10, 10, QtWidgets.QSizePolicy.Policy.Fixed,
QtWidgets.QSizePolicy.Policy.Fixed), 8, 0, 1, 20)
layout.addItem(QtWidgets.QSpacerItem(
10, 10, QtWidgets.QSizePolicy.Policy.Expanding,
QtWidgets.QSizePolicy.Policy.Expanding), 12, 0, 1, 20)
asterisco = QtWidgets.QLabel("*")
asterisco.setFont(font20)
asterisco.setAlignment(alignment)
layout.addWidget(asterisco, 6, 3)
asterisco2 = QtWidgets.QLabel("**")
asterisco2.setFont(font20)
asterisco2.setAlignment(alignment)
layout.addWidget(asterisco2, 7, 3)
asterisco_ = QtWidgets.QLabel("*")
asterisco_.setFont(font20)
asterisco_.setAlignment(alignment)
layout.addWidget(asterisco_, 10, 2)
asterisco2_ = QtWidgets.QLabel("**")
asterisco2_.setFont(font20)
asterisco2_.setAlignment(alignment)
layout.addWidget(asterisco2_, 11, 2)
butonConfig = QtWidgets.QToolButton()
butonConfig.setIcon(QtGui.QIcon(
os.environ["pychemqt"]
+ os.path.join("images", "button", "configure.png")))
butonConfig.clicked.connect(self.configure)
layout.addWidget(butonConfig, 11, 1)
self.Info = QtWidgets.QFrame()
layout.addWidget(self.Info, 0, 5, 3, 3)
layoutInfo = QtWidgets.QGridLayout(self.Info)
layoutInfo.setSpacing(1)
layoutInfo.setContentsMargins(2, 0, 2, 0)
self.Info.setFrameShape(QtWidgets.QFrame.Shape.StyledPanel)
self.Info.setFrameShadow(QtWidgets.QFrame.Shadow.Raised)
self.Info.setAutoFillBackground(True)
self.Info.setPalette(palette)
self.numero_atomico = QtWidgets.QLabel()
self.numero_atomico.setToolTip(self.tr("Atomic number"))
layoutInfo.addWidget(self.numero_atomico, 1, 1)
self.simbolo = QtWidgets.QLabel()
self.simbolo.setAlignment(alignment)
self.simbolo.setToolTip(self.tr("Symbol"))
self.simbolo.setFont(font11)
layoutInfo.addWidget(self.simbolo, 1, 3)
self.nombre = QtWidgets.QLabel()
self.nombre.setAlignment(QtCore.Qt.AlignmentFlag.AlignCenter)
self.nombre.setFont(font_title)
layoutInfo.addWidget(self.nombre, 2, 1, 1, 3)
font8 = QtGui.QFont()
font8.setPointSize(8)
self.peso_atomico = QtWidgets.QLabel()
self.peso_atomico.setFont(font8)
self.peso_atomico.setToolTip(self.tr("Atomic mass, g/mol"))
layoutInfo.addWidget(self.peso_atomico, 3, 1)
self.densidad = QtWidgets.QLabel()
self.densidad.setFont(font8)
self.densidad.setAlignment(alignment)
self.densidad.setToolTip(self.tr(
"Density:\nBrown: Solid, kg/l\nBlue: Liquid, kg/l\n"
"Green: Gas, g/l"))
layoutInfo.addWidget(self.densidad, 3, 3)
self.Tf = QtWidgets.QLabel()
self.Tf.setFont(font8)
self.Tf.setToolTip(self.tr("Melting Point, K"))
layoutInfo.addWidget(self.Tf, 4, 1)
self.Heat_f = QtWidgets.QLabel()
self.Heat_f.setFont(font8)
self.Heat_f.setToolTip(self.tr("Heat of fusion, kJmol"))
self.Heat_f.setAlignment(alignment)
layoutInfo.addWidget(self.Heat_f, 4, 3)
self.Tb = QtWidgets.QLabel()
self.Tb.setFont(font8)
self.Tb.setToolTip(self.tr("Boiling Point, K"))
layoutInfo.addWidget(self.Tb, 5, 1)
self.Heat_b = QtWidgets.QLabel()
self.Heat_b.setFont(font8)
self.Heat_b.setToolTip(self.tr("Heat of vaporization, kJmol"))
self.Heat_b.setAlignment(alignment)
layoutInfo.addWidget(self.Heat_b, 5, 3)
self.configuracion = QtWidgets.QLabel()
self.configuracion.setFont(font7)
self.configuracion.setAlignment(QtCore.Qt.AlignmentFlag.AlignCenter)
self.configuracion.setToolTip(self.tr("Electronic configuration"))
layoutInfo.addWidget(self.configuracion, 6, 1, 1, 3)
self.Info2 = QtWidgets.QFrame()
layout.addWidget(self.Info2, 0, 8, 3, 3)
layoutInfo2 = QtWidgets.QGridLayout(self.Info2)
layoutInfo2.setSpacing(1)
layoutInfo2.setContentsMargins(2, 0, 2, 0)
self.Info2.setFrameShape(QtWidgets.QFrame.Shape.StyledPanel)
self.Info2.setFrameShadow(QtWidgets.QFrame.Shadow.Raised)
self.Info2.setAutoFillBackground(True)
self.Info2.setPalette(palette)
self.atomic_volume = QtWidgets.QLabel()
self.atomic_volume.setFont(font8)
self.atomic_volume.setToolTip(self.tr("Atomic volume")+", cm³/mol")
layoutInfo2.addWidget(self.atomic_volume, 1, 1)
self.atomic_radius = QtWidgets.QLabel()
self.atomic_radius.setFont(font8)
self.atomic_radius.setToolTip(self.tr("Atomic radius") + ", pm")
layoutInfo2.addWidget(self.atomic_radius, 2, 1)
self.covalent_radius = QtWidgets.QLabel()
self.covalent_radius.setFont(font8)
self.covalent_radius.setToolTip(self.tr("Covalent radius") + ", pm")
layoutInfo2.addWidget(self.covalent_radius, 3, 1)
self.vanderWaals_radius = QtWidgets.QLabel()
self.vanderWaals_radius.setFont(font8)
self.vanderWaals_radius.setToolTip(
self.tr("Van der Waals radius")+", pm")
layoutInfo2.addWidget(self.vanderWaals_radius, 4, 1)
self.ionic_radii = QtWidgets.QLabel()
self.ionic_radii.setFont(font7)
self.ionic_radii.setToolTip(self.tr("Ionic radii")+", pm")
layoutInfo2.addWidget(self.ionic_radii, 5, 1, 1, 3)
self.electronegativity = QtWidgets.QLabel()
self.electronegativity.setFont(font8)
self.electronegativity.setToolTip(
self.tr("Electronegativity, Pauling scale"))
self.electronegativity.setAlignment(
QtCore.Qt.AlignmentFlag.AlignRight
| QtCore.Qt.AlignmentFlag.AlignVCenter)
layoutInfo2.addWidget(self.electronegativity, 1, 3)
self.Cp = QtWidgets.QLabel()
self.Cp.setFont(font8)
self.Cp.setToolTip(self.tr("Specific heat capacitiy") + ", kJ/kgK")
self.Cp.setAlignment(QtCore.Qt.AlignmentFlag.AlignRight
| QtCore.Qt.AlignmentFlag.AlignVCenter)
layoutInfo2.addWidget(self.Cp, 2, 3)
self.k = QtWidgets.QLabel()
self.k.setFont(font8)
self.k.setToolTip(self.tr("Thermal conductivity") + ", W/mK")
self.k.setAlignment(QtCore.Qt.AlignmentFlag.AlignRight
| QtCore.Qt.AlignmentFlag.AlignVCenter)
layoutInfo2.addWidget(self.k, 3, 3)
self.first_ionization = QtWidgets.QLabel()
self.first_ionization.setFont(font8)
self.first_ionization.setToolTip(
self.tr("First ionization energy") + ", kJ/mol")
self.first_ionization.setAlignment(
QtCore.Qt.AlignmentFlag.AlignRight
| QtCore.Qt.AlignmentFlag.AlignVCenter)
layoutInfo2.addWidget(self.first_ionization, 4, 3)
self.oxidation = QtWidgets.QLabel()
self.oxidation.setFont(font8)
self.oxidation.setToolTip(self.tr("Oxidation states"))
self.oxidation.setAlignment(QtCore.Qt.AlignmentFlag.AlignCenter
| QtCore.Qt.AlignmentFlag.AlignVCenter)
layoutInfo2.addWidget(self.oxidation, 6, 1, 1, 3)
elemento = Elemental(1)
self.actualizar(elemento)
logging.info(self.tr("Starting periodic table tool"))
[docs]
def populate(self):
"""Populate buttons in table"""
CATEGORIES, PROP, COLORS, PMAX = _configValues(self.Preferences)
for i in range(1, 119):
element = Elemental(i)
b = boton(element, CATEGORIES, PROP, COLORS, PMAX, self)
if element.group == 0:
if i < 80:
j = i-58
else:
j = i-90
self.layout().addWidget(b, element.period+4, j+4)
elif i in (57, 89):
self.layout().addWidget(b, element.period+4, element.group)
else:
self.layout().addWidget(b, element.period, element.group)
[docs]
def actualizar(self, elemento):
"""Update botton info with data for current element"""
self.numero_atomico.setText(str(elemento.id))
self.nombre.setText(elemento.name)
self.simbolo.setText(elemento.symbol)
self.textData(self.peso_atomico, elemento.atomic_mass)
if elemento.density_Solid:
color = "#A52A2A"
value = elemento.density_Solid
elif elemento.density_Liq:
color = "#0000FF"
value = elemento.density_Liq
elif elemento.density_Gas:
color = "#0A640A"
value = elemento.density_Gas
else:
color = "#888888"
value = "N/A"
self.densidad.setText(f"<font color={color}>{value}</font>")
self.textData(self.Tf, elemento.Tf, color="#0000C8")
self.textData(self.Heat_f, elemento.Heat_f, color="#0000C8")
self.textData(self.Tb, elemento.Tb, color="#C80000")
self.textData(self.Heat_b, elemento.Heat_b, color="#C80000")
self.textData(self.configuracion, elemento.electron_configuration)
self.textData(self.atomic_volume, elemento.atomic_volume)
self.textData(self.atomic_radius, elemento.atomic_radius)
self.textData(self.ionic_radii, elemento.ionic_radii)
self.textData(self.covalent_radius, elemento.covalent_radius)
self.textData(self.vanderWaals_radius, elemento.vanderWaals_radius)
self.textData(self.electronegativity, elemento.electronegativity)
self.textData(self.Cp, elemento.Cp)
self.textData(self.k, elemento.k)
self.textData(self.first_ionization, elemento.first_ionization)
self.textData(self.oxidation, elemento.oxidation)
[docs]
def textData(self, widget, data, color="#000000", color_dis="#888888"):
"""Set text and format for property in button"""
if not data:
widget.setText(f"<font color={color_dis}>N/A</font>")
else:
widget.setText(f"<font color={color}>{data}</font>")
[docs]
class boton(QtWidgets.QPushButton):
"""Button widget to define a element"""
[docs]
def __init__(self, element, CATEGORIES, PROP, COLORS, PMAX, parent=None):
"""Constructor,
element: the atomic number, used as id to tagged button
"""
super().__init__(parent)
self.setFixedSize(40, 35)
self.setToolTip(self.tr("Click for view properties"))
self.parent = parent
self.Element = element
if COLORS and not PMAX:
if PROP == "group_element":
PROP = "group"
prop = element.__getattribute__(PROP)
color = COLORS[CATEGORIES.index(prop)]
elif PMAX:
prop = cleanFloat(element.__getattribute__(PROP))
if prop:
if prop > CATEGORIES[-1]:
color = COLORS[-1]
else:
index = 1
while True:
if prop <= CATEGORIES[index]:
color = COLORS[index-1]
break
index += 1
else:
color = "#DDDDDD"
else:
color = self.Element.color
self.setStyleSheet("QPushButton { background-color: %s }" % color)
self.setText(self.Element.symbol)
self.clicked.connect(self.press)
[docs]
def enterEvent(self, event):
"""Enter event to change boton info with new element data"""
self.parent.actualizar(self.Element)
event.accept()
[docs]
def press(self):
"""Press button show elementDialog with other element data"""
dialog = ElementDialog(self.Element)
dialog.exec()
[docs]
class ElementDialog(QtWidgets.QDialog):
"""Dialog to show all element properties"""
[docs]
def __init__(self, elemento, parent=None):
super().__init__(parent)
self.setWindowTitle(self.tr("Properties of "+elemento.name))
lyt = QtWidgets.QVBoxLayout(self)
tabWidget = QtWidgets.QTabWidget()
lyt.addWidget(tabWidget)
btbox = QtWidgets.QDialogButtonBox(
QtWidgets.QDialogButtonBox.StandardButton.Close)
btbox.rejected.connect(self.reject)
lyt.addWidget(btbox)
tabGeneral = QtWidgets.QWidget()
layoutGeneral = QtWidgets.QGridLayout(tabGeneral)
layoutGeneral.addWidget(QtWidgets.QLabel(self.tr("Name:")), 1, 1)
layoutGeneral.addWidget(QtWidgets.QLabel(elemento.name), 1, 2)
layoutGeneral.addWidget(QtWidgets.QLabel(self.tr("Serie:")), 2, 1)
layoutGeneral.addWidget(QtWidgets.QLabel(elemento.serie), 2, 2)
layoutGeneral.addWidget(QtWidgets.QLabel(self.tr("Group")), 3, 1)
layoutGeneral.addWidget(QtWidgets.QLabel(str(elemento.group)), 3, 2)
layoutGeneral.addWidget(QtWidgets.QLabel(self.tr("Period")), 4, 1)
layoutGeneral.addWidget(QtWidgets.QLabel(str(elemento.period)), 4, 2)
layoutGeneral.addWidget(QtWidgets.QLabel(self.tr("Block")), 5, 1)
layoutGeneral.addWidget(QtWidgets.QLabel(elemento.block), 5, 2)
layoutGeneral.addItem(QtWidgets.QSpacerItem(
20, 20, QtWidgets.QSizePolicy.Policy.Fixed,
QtWidgets.QSizePolicy.Policy.Fixed), 6, 1)
label = QtWidgets.QLabel(self.tr("History"))
font = QtGui.QFont()
font.setWeight(75)
font.setBold(True)
label.setFont(font)
layoutGeneral.addWidget(label, 7, 1, 1, 3)
label_8 = QtWidgets.QLabel(
self.tr("Discovery") + ": "
+ elemento.country + "(" + elemento.country + ")" + os.linesep
+ self.tr("Discovered by ") + elemento.discover + os.linesep
+ self.tr("Etymology") + ": " + elemento.etymology)
label_8.setMargin(5)
label_8.setWordWrap(True)
layoutGeneral.addWidget(label_8, 8, 1, 1, 3)
self.botoncito = QtWidgets.QLabel()
self.botoncito.setStyleSheet(f"background-color: {elemento.color};")
self.botoncito.setFrameShape(QtWidgets.QFrame.Shape.StyledPanel)
self.botoncito.setFixedSize(60, 60)
layoutGeneral.addWidget(self.botoncito, 1, 5, 3, 1)
label = QtWidgets.QLabel()
label.setText(str(elemento.id))
label.setAlignment(QtCore.Qt.AlignmentFlag.AlignCenter
| QtCore.Qt.AlignmentFlag.AlignBottom)
layoutGeneral.addWidget(label, 1, 5)
label = QtWidgets.QLabel(elemento.symbol)
font.setPointSize(12)
label.setFont(font)
label.setAlignment(QtCore.Qt.AlignmentFlag.AlignCenter
| QtCore.Qt.AlignmentFlag.AlignBottom)
layoutGeneral.addWidget(label, 2, 5)
layoutGeneral.addItem(QtWidgets.QSpacerItem(
20, 20, QtWidgets.QSizePolicy.Policy.Expanding,
QtWidgets.QSizePolicy.Policy.Expanding), 9, 3)
tabWidget.addTab(tabGeneral, self.tr("General"))
tabFisica = QtWidgets.QWidget()
lytphy = QtWidgets.QGridLayout(tabFisica)
lytphy.addWidget(QtWidgets.QLabel(self.tr("Fase:")), 1, 1)
lytphy.addWidget(QtWidgets.QLabel(
elemento.phase + " a 0ºC"), 1, 2, 1, 1)
if elemento.density_Solid:
lytphy.addWidget(QtWidgets.QLabel(self.tr("Solid Density:")), 2, 1)
lytphy.addWidget(self.drawData(
unidades.Density, elemento.density_Solid,
"gcc", txt=" @ 20ºC"), 2, 2)
if elemento.density_Liq:
lytphy.addWidget(QtWidgets.QLabel(
self.tr("Liquid Density:")), 3, 1)
lytphy.addWidget(self.drawData(
unidades.Density, elemento.density_Liq, "gcc", txt=" "
+ self.tr("at melting point")), 3, 2)
if elemento.density_Gas:
lytphy.addWidget(QtWidgets.QLabel(self.tr("Gas Density:")), 4, 1)
lytphy.addWidget(self.drawData(
unidades.Density, elemento.density_Gas, "gl", txt=" @ 0ºC"),
4, 2)
lytphy.addWidget(QtWidgets.QLabel(self.tr("Appearance:")), 5, 1)
label = QtWidgets.QLabel(elemento.appearance)
label.setWordWrap(True)
lytphy.addWidget(label, 5, 2)
lytphy.addItem(QtWidgets.QSpacerItem(
20, 20, QtWidgets.QSizePolicy.Policy.Fixed,
QtWidgets.QSizePolicy.Policy.Fixed), 6, 1, 1, 3)
label = QtWidgets.QLabel(self.tr("Thermal properties"))
label.setFont(font)
lytphy.addWidget(label, 7, 1)
lytphy.addWidget(QtWidgets.QLabel(self.tr("Melting point:")), 8, 1)
self.punto_fusion = self.drawData(
unidades.Temperature, elemento.Tf)
lytphy.addWidget(self.punto_fusion, 8, 2)
lytphy.addWidget(QtWidgets.QLabel(self.tr("Boiling point:")), 9, 1)
self.punto_ebullicion = self.drawData(
unidades.Temperature, elemento.Tb)
lytphy.addWidget(self.punto_ebullicion, 9, 2)
lytphy.addWidget(QtWidgets.QLabel(self.tr("Heat of fusion:")), 10, 1)
self.calor_fusion = self.drawData(
unidades.MolarEnthalpy, elemento.Heat_f, "kJkmol")
lytphy.addWidget(self.calor_fusion, 10, 2)
lytphy.addWidget(QtWidgets.QLabel(
self.tr("Heat of vaporization:")), 11, 1)
self.calor_vaporizacion = self.drawData(
unidades.MolarEnthalpy, elemento.Heat_b, "kJkmol")
lytphy.addWidget(self.calor_vaporizacion, 11, 2)
lytphy.addWidget(QtWidgets.QLabel(
self.tr("Specific heat capacity:")), 12, 1)
self.capacidad_calorifica = self.drawData(
unidades.SpecificHeat, elemento.Cp, "JgK")
lytphy.addWidget(self.capacidad_calorifica, 12, 2)
lytphy.addWidget(QtWidgets.QLabel(
self.tr("Thermal conductivity:")), 13, 1)
self.conductividad_termica = self.drawData(
unidades.ThermalConductivity, elemento.k, txt=" @ 300K")
lytphy.addWidget(self.conductividad_termica, 13, 2)
lytphy.addWidget(QtWidgets.QLabel(
self.tr("Debye Temperature:")), 14, 1)
self.temperatura_debye = self.drawData(
unidades.Temperature, elemento.T_debye)
lytphy.addWidget(self.temperatura_debye, 14, 2)
lytphy.addItem(QtWidgets.QSpacerItem(
20, 20, QtWidgets.QSizePolicy.Policy.Expanding,
QtWidgets.QSizePolicy.Policy.Expanding), 15, 1, 1, 3)
tabWidget.addTab(tabFisica, self.tr("Physical properties"))
tabAtom = QtWidgets.QWidget()
lyt_A = QtWidgets.QGridLayout(tabAtom)
lyt_A.addWidget(QtWidgets.QLabel(self.tr("Atomic mass:")), 1, 1)
if elemento.atomic_mass:
self.masa_atomica = QtWidgets.QLabel(
str(elemento.atomic_mass) + " g/mol")
else:
self.masa_atomica = QtWidgets.QLabel(elemento.atomic_mass)
lyt_A.addWidget(self.masa_atomica, 1, 2)
lyt_A.addWidget(QtWidgets.QLabel(self.tr("Atomic Volume:")), 2, 1)
self.volumen_atomico = self.drawData(
unidades.MolarVolume, elemento.atomic_volume)
lyt_A.addWidget(self.volumen_atomico, 2, 2)
lyt_A.addWidget(QtWidgets.QLabel(self.tr("Atomic radius:")), 3, 1)
if elemento.atomic_radius:
self.radio_atomico = QtWidgets.QLabel(
str(elemento.atomic_radius) + " pm")
else:
self.radio_atomico = QtWidgets.QLabel(str(elemento.atomic_radius))
lyt_A.addWidget(self.radio_atomico, 3, 2)
lyt_A.addWidget(QtWidgets.QLabel(self.tr("Covalent radius:")), 4, 1)
if elemento.covalent_radius:
self.radio_covalente = QtWidgets.QLabel(
str(elemento.covalent_radius) + " pm")
else:
self.radio_covalente = QtWidgets.QLabel(
str(elemento.covalent_radius))
lyt_A.addWidget(self.radio_covalente, 4, 2)
lyt_A.addWidget(QtWidgets.QLabel(
self.tr("Van der Waals radius:")), 5, 1)
if elemento.vanderWaals_radius:
self.radio_waals = QtWidgets.QLabel(
str(elemento.vanderWaals_radius) + " pm")
else:
self.radio_waals = QtWidgets.QLabel(
str(elemento.vanderWaals_radius))
lyt_A.addWidget(self.radio_waals, 5, 2)
lyt_A.addWidget(QtWidgets.QLabel(self.tr("Ionic radii:")), 6, 1)
if elemento.ionic_radii:
self.radio_ionico = QtWidgets.QLabel(
str(elemento.ionic_radii) + " pm")
else:
self.radio_ionico = QtWidgets.QLabel(str(elemento.ionic_radii))
lyt_A.addWidget(self.radio_ionico, 6, 2)
lyt_A.addItem(QtWidgets.QSpacerItem(
20, 20, QtWidgets.QSizePolicy.Policy.Fixed,
QtWidgets.QSizePolicy.Policy.Fixed), 7, 1, 1, 3)
label = QtWidgets.QLabel(self.tr("Electronic properties"))
label.setFont(font)
lyt_A.addWidget(label, 8, 1)
lyt_A.addWidget(QtWidgets.QLabel(
self.tr("Electronic configuration:")), 9, 1)
lyt_A.addWidget(QtWidgets.QLabel(
elemento.electron_configuration), 9, 2)
lyt_A.addWidget(QtWidgets.QLabel(self.tr("Oxidation states:")), 10, 1)
lyt_A.addWidget(QtWidgets.QLabel(
elemento.oxidation), 10, 2)
lyt_A.addWidget(QtWidgets.QLabel(self.tr("Electronegativity:")), 11, 1)
lyt_A.addWidget(QtWidgets.QLabel(
str(elemento.electronegativity)), 11, 2)
lyt_A.addWidget(QtWidgets.QLabel(self.tr("Electron affinity:")), 12, 1)
self.afinidad_electronica = self.drawData(
unidades.MolarEnthalpy, elemento.electron_affinity, "kJkmol")
lyt_A.addWidget(self.afinidad_electronica, 12, 2)
lyt_A.addWidget(QtWidgets.QLabel(
self.tr("1st ionization energy:")), 13, 1)
self.energia_ionizacion = self.drawData(
unidades.MolarEnthalpy, elemento.first_ionization, "kJkmol")
lyt_A.addWidget(self.energia_ionizacion, 13, 2)
lyt_A.addItem(QtWidgets.QSpacerItem(
20, 20, QtWidgets.QSizePolicy.Policy.Expanding,
QtWidgets.QSizePolicy.Policy.Expanding), 14, 1, 1, 3)
tabWidget.addTab(tabAtom, self.tr("Atomic properties"))
tabCristal = QtWidgets.QWidget()
lyt_C = QtWidgets.QGridLayout(tabCristal)
lyt_C.addWidget(QtWidgets.QLabel(self.tr("Lattice type:")), 1, 1)
lyt_C.addWidget(QtWidgets.QLabel(
elemento.lattice_type), 1, 2)
lyt_C.addWidget(QtWidgets.QLabel(self.tr("Space group:")), 2, 1)
lyt_C.addWidget(QtWidgets.QLabel(
elemento.space_group), 2, 2)
lyt_C.addWidget(QtWidgets.QLabel(
self.tr("Lattice edge lengths:")), 3, 1)
self.lados = QtWidgets.QLabel()
if elemento.lattice_edges:
self.lados.setText(f"{elemento.lattice_edges[0]}pm, "
f"{elemento.lattice_edges[1]}pm, "
f"{elemento.lattice_edges[2]}pm")
else:
self.lados.setText(elemento.lattice_edges)
lyt_C.addWidget(self.lados, 3, 2)
lyt_C.addWidget(QtWidgets.QLabel(self.tr("Lattice angles:")), 4, 1)
self.angulos = QtWidgets.QLabel()
if elemento.lattice_angles:
self.angulos.setText(f"{elemento.lattice_angles[0]}º "
f"{elemento.lattice_angles[1]}º "
f"{elemento.lattice_angles[2]}º")
else:
self.angulos.setText(elemento.lattice_angles)
lyt_C.addWidget(self.angulos, 4, 2)
lyt_C.addWidget(QtWidgets.QLabel(
self.tr("Lattice unit volume:")), 5, 1)
self.volumen_celda = QtWidgets.QLabel()
if elemento.lattice_angles:
self.volumen_celda.setText(
f"{elemento.lattice_volume:0.5f} mm<sup>3</sup>")
else:
self.volumen_celda.setText(elemento.lattice_volume)
lyt_C.addWidget(self.volumen_celda, 5, 2)
lyt_C.addItem(QtWidgets.QSpacerItem(
20, 20, QtWidgets.QSizePolicy.Policy.Expanding,
QtWidgets.QSizePolicy.Policy.Expanding), 6, 1, 1, 3)
label = QtWidgets.QLabel(self.tr("Isotopes"))
label.setFont(font)
lyt_C.addWidget(label, 8, 1)
title = [self.tr("Mass Number"), self.tr("Mass"), self.tr("Abundance")]
self.isotopes = Tabla(3, horizontalHeader=title, readOnly=True,
stretch=True, verticalHeader=False)
self.isotopes.setSelectionBehavior(
QtWidgets.QAbstractItemView.SelectionBehavior.SelectRows)
self.isotopes.setColumn(
0, [iso[0] for iso in elemento.isotopes], decimales=0)
self.isotopes.setColumn(
1, [iso[1] for iso in elemento.isotopes], fmt=1, decimales=10)
self.isotopes.setColumn(
2, [iso[2] for iso in elemento.isotopes], fmt=1, decimales=10)
lyt_C.addWidget(self.isotopes, 9, 1, 1, 2)
lyt_C.addItem(QtWidgets.QSpacerItem(
20, 20, QtWidgets.QSizePolicy.Policy.Expanding,
QtWidgets.QSizePolicy.Policy.Expanding), 10, 1, 1, 3)
tabWidget.addTab(tabCristal, self.tr("Crystallographic"))
[docs]
def drawData(self, unit, data, unidad="", txt=""):
"""Return a widget with the data inprint
unit: unidad subclass
data: value to set
unidad: unit of value to show
txt: opcional txt to show for unit"""
if data and unidad:
value = unit(data, unidad)
widget = Entrada_con_unidades(
unit, readOnly=True, value=value, textounidad=txt)
elif data:
widget = Entrada_con_unidades(
unit, readOnly=True, value=data, textounidad=txt)
else:
widget = QtWidgets.QLabel(str(data))
return widget
[docs]
class Config(QtWidgets.QWidget):
"""External applications configuration"""
[docs]
def __init__(self, config=None, parent=None):
super().__init__(parent)
layout = QtWidgets.QGridLayout(self)
layout.addWidget(QtWidgets.QLabel(self.tr("Color by element:")), 1, 1)
colorby = ["Element", "serie", "group_element", "period", "block",
"phase", "lattice_type", "space_group", "density_Solid",
"density_Liq", "density_Gas", "date", "atomic_mass",
"atomic_volume", "atomic_radius", "covalent_radius",
"vanderWaals_radius", "electronegativity",
"electron_affinity", "first_ionization", "Tf", "Tb",
"Heat_f", "Heat_b", "Cp", "k", "T_debye"]
self.ElementalColorby = QtWidgets.QComboBox()
for c in colorby:
self.ElementalColorby.addItem(c)
layout.addWidget(self.ElementalColorby, 1, 2)
layout.addWidget(QtWidgets.QLabel(
self.tr("Color definition")), 2, 1)
self.ElementalDefinition = QtWidgets.QSpinBox()
self.ElementalDefinition.setMaximumWidth(50)
self.ElementalDefinition.setMinimum(5)
layout.addWidget(self.ElementalDefinition, 2, 2)
self.ElementalLog = QtWidgets.QCheckBox(self.tr("Logarithmic scale"))
layout.addWidget(self.ElementalLog, 3, 1, 1, 2)
layout.addItem(QtWidgets.QSpacerItem(
0, 0, QtWidgets.QSizePolicy.Policy.Expanding,
QtWidgets.QSizePolicy.Policy.Expanding), 4, 3)
if config.has_section("Applications"):
self.ElementalColorby.setCurrentText(
config.get("Applications", 'elementalColorby'))
self.ElementalDefinition.setValue(
config.getint("Applications", 'elementalDefinition'))
self.ElementalLog.setChecked(
config.getboolean("Applications", 'elementalLog'))
[docs]
def value(self, config):
"""Return value for main dialog"""
if not config.has_section("Applications"):
config.add_section("Applications")
config.set("Applications", "elementalColorby",
self.ElementalColorby.currentText())
config.set("Applications", "elementalDefinition",
str(self.ElementalDefinition.value()))
config.set("Applications", "elementalLog",
str(self.ElementalLog.isChecked()))
return config
[docs]
class ConfigDialog(QtWidgets.QDialog):
"""Dialog to config thermal method calculations"""
[docs]
def __init__(self, config=None, parent=None):
super().__init__(parent)
self.setWindowTitle(self.tr("Qtelemental configuration"))
layout = QtWidgets.QVBoxLayout(self)
self.widget = Config(config)
layout.addWidget(self.widget)
self.buttonBox = QtWidgets.QDialogButtonBox(
QtWidgets.QDialogButtonBox.StandardButton.Cancel
| QtWidgets.QDialogButtonBox.StandardButton.Ok)
self.buttonBox.accepted.connect(self.accept)
self.buttonBox.rejected.connect(self.reject)
layout.addWidget(self.buttonBox)
[docs]
def value(self, config):
"""Function result for wizard"""
config = self.widget.value(config)
return config
if __name__ == "__main__":
import sys
app = QtWidgets.QApplication(sys.argv)
Form = qtelemental()
Form.show()
sys.exit(app.exec())