Source code for tools.UI_confUnits
#!/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/>.
Dialog to define the units used in the projects. Allows you to select the \
preferred unit for each of the magnitudes used in the program. The main \
measurement systems (SI, british, AltSI, Metric, CGS) that can be directly \
selected also have predefined. Also allow to save and then load personalized \
units profiles. That profiles are saved in unitrc file in the main program \
config folder.
.. image:: images/UI_confUnits.png
:alt: UI_confUnits
The module include all related prefered units functionality:
* :class:`UI_confUnits_widget`: Units configuration widget, to use in \
whatever need, dialog, wizard...
* :class:`Dialog`: Standalone dialog
API reference
-------------
'''
from ast import literal_eval
from configparser import ConfigParser
from functools import partial
import os
from tools.qt import QtGui, QtWidgets
from lib import unidades
from lib.config import conf_dir, IMAGE_PATH
[docs]
class UI_confUnits_widget(QtWidgets.QWidget):
"""Units widget, to use in whatever need, dialog, wizard..."""
[docs]
def __init__(self, config=None, parent=None):
"""Constructor, opcional config paramater with project config"""
super().__init__(parent)
lyt = QtWidgets.QGridLayout(self)
systems = QtWidgets.QGroupBox(self.tr("Systems of measurement"))
systems.setSizePolicy(QtWidgets.QSizePolicy.Policy.Preferred,
QtWidgets.QSizePolicy.Policy.Fixed)
lyt.addWidget(systems, 1, 1, 1, 2)
lytSystems = QtWidgets.QHBoxLayout(systems)
self.SI = QtWidgets.QRadioButton(self.tr("SI"))
self.SI.toggled.connect(partial(self.load, "si"))
lytSystems.addWidget(self.SI)
self.AltSI = QtWidgets.QRadioButton(self.tr("Alt SI"))
self.AltSI.toggled.connect(partial(self.load, "altsi"))
lytSystems.addWidget(self.AltSI)
self.English = QtWidgets.QRadioButton(self.tr("English"))
self.English.toggled.connect(partial(self.load, "english"))
lytSystems.addWidget(self.English)
self.Metric = QtWidgets.QRadioButton(self.tr("Metric"))
self.Metric.toggled.connect(partial(self.load, "metric"))
lytSystems.addWidget(self.Metric)
self.CGS = QtWidgets.QRadioButton(self.tr("CGS"))
self.CGS.toggled.connect(partial(self.load, "cgs"))
lytSystems.addWidget(self.CGS)
lyt.addItem(QtWidgets.QSpacerItem(
10, 10, QtWidgets.QSizePolicy.Policy.Fixed,
QtWidgets.QSizePolicy.Policy.Fixed), 2, 1, 1, 2)
table = QtWidgets.QTableWidget()
lyt.addWidget(table, 3, 1, 5, 1)
table.setRowCount(len(unidades.MAGNITUDES)-1)
table.setColumnCount(1)
table.horizontalHeader().setVisible(False)
self.combos = []
for i, magnitud in enumerate(unidades.MAGNITUDES[:-1]):
table.setVerticalHeaderItem(
i, QtWidgets.QTableWidgetItem(magnitud[1]))
table.setRowHeight(i, 24)
combo = QtWidgets.QComboBox()
if magnitud[0] == "Currency":
for texto, unidad in zip(magnitud[2].__text__,
magnitud[2].__units__):
combo.addItem(QtGui.QIcon(QtGui.QPixmap(os.path.join(
IMAGE_PATH, "flag", f"{unidad}.gif"))),
texto + " - " + unidad)
else:
for unidad in magnitud[2].__text__:
combo.addItem(unidad)
self.combos.append(combo)
table.setCellWidget(i, 0, combo)
table.resizeColumnToContents(0)
table.setFixedWidth(table.verticalHeader().sizeHint().width()
+ table.columnWidth(0) + 20)
self.name = QtWidgets.QLineEdit()
self.name.textChanged.connect(self.nameChanged)
lyt.addWidget(self.name, 3, 2)
self.Guardar = QtWidgets.QPushButton(QtGui.QIcon(QtGui.QPixmap(
os.path.join(IMAGE_PATH, "button", "fileSave.png"))),
self.tr("Save profile"))
self.Guardar.setEnabled(False)
self.Guardar.clicked.connect(self.save)
lyt.addWidget(self.Guardar, 4, 2)
self.profiles = QtWidgets.QComboBox()
lyt.addWidget(self.profiles, 6, 2)
self.loadButton = QtWidgets.QPushButton(QtGui.QIcon(QtGui.QPixmap(
os.path.join(IMAGE_PATH, "button", "fileOpen.png"))),
self.tr("Load profile"))
self.loadButton.clicked.connect(self.load)
lyt.addWidget(self.loadButton, 7, 2)
self.updateProfileList()
if config and config.has_section("Units"):
if config.getint("Units", "System") == 0:
self.SI.setChecked(True)
self.load("si")
elif config.getint("Units", "System") == 1:
self.Metric.setChecked(True)
self.load("metric")
elif config.getint("Units", "System") == 2:
self.CGS.setChecked(True)
self.load("cgs")
elif config.getint("Units", "System") == 3:
self.English.setChecked(True)
self.load("english")
elif config.getint("Units", "System") == 4:
self.AltSI.setChecked(True)
self.load("altsi")
for combo, magnitud in zip(self.combos, unidades.MAGNITUDES[:-1]):
combo.setCurrentIndex(config.getint("Units", magnitud[0]))
[docs]
def updateProfileList(self):
"""Update custom units profile list"""
self.profiles.clear()
if os.path.isfile(conf_dir+"unitrc"):
Config = ConfigParser()
Config.read(conf_dir+"unitrc")
for i in Config.options("units"):
self.profiles.addItem(self.tr(i))
self.profiles.setEnabled(True)
self.loadButton.setEnabled(True)
else:
self.profiles.setEnabled(False)
self.loadButton.setEnabled(False)
[docs]
def save(self):
"""Save units profile to a file"""
lista = []
for combo in self.combos:
lista.append(combo.currentIndex())
Config = ConfigParser()
if os.path.isfile(conf_dir+"unitrc"):
Config.read(conf_dir+"unitrc")
else:
Config.add_section("units")
Config.set("units", str(self.name.text()), str(lista))
with open(conf_dir+"unitrc", "w") as unit_file:
Config.write(unit_file)
self.updateProfileList()
[docs]
def nameChanged(self, name):
"""Update state of boton Guardar"""
self.Guardar.setEnabled(bool(name))
[docs]
def load(self, unitset=None):
"""Load unit set, opcional set parameter can be any of predefined:
si, altsi, metric, cgs, english"""
if unitset:
lista = unidades.units_set[unitset]
else:
Config = ConfigParser()
Config.read(conf_dir+"unitrc")
lista = literal_eval(
Config.get("units", str(self.profiles.currentText())))
for combo, indice in zip(self.combos, lista):
combo.setCurrentIndex(indice)
[docs]
def value(self, config):
"""Function to wizard result"""
if not config.has_section("Units"):
config.add_section("Units")
if self.SI.isChecked():
config.set("Units", "System", "0")
elif self.Metric.isChecked():
config.set("Units", "System", "1")
elif self.CGS.isChecked():
config.set("Units", "System", "2")
elif self.English.isChecked():
config.set("Units", "System", "3")
elif self.AltSI.isChecked():
config.set("Units", "System", "4")
else:
config.set("Units", "System", "5")
for combo, magnitud in zip(self.combos, unidades.MAGNITUDES[:-1]):
config.set("Units", magnitud[0], str(combo.currentIndex()))
return config
[docs]
@classmethod
def default(cls, config):
"""Default configuration"""
config.add_section("Units")
config.set("Units", "System", "0")
for magnitud in unidades.MAGNITUDES[:-1]:
config.set("Units", magnitud[0], "0")
return config
[docs]
class Dialog(QtWidgets.QDialog):
"""Units configuration dialog"""
[docs]
def __init__(self, config=None, parent=None):
super().__init__(parent)
self.setWindowTitle(self.tr("Units"))
lyt = QtWidgets.QVBoxLayout(self)
self.datos = UI_confUnits_widget(config)
lyt.addWidget(self.datos)
self.buttonBox = QtWidgets.QDialogButtonBox(
QtWidgets.QDialogButtonBox.StandardButton.Cancel
| QtWidgets.QDialogButtonBox.StandardButton.Ok)
self.buttonBox.accepted.connect(self.accept)
self.buttonBox.rejected.connect(self.reject)
lyt.addWidget(self.buttonBox)
[docs]
def value(self, config):
"""Function to wizard result"""
config = self.datos.value(config)
return config
if __name__ == "__main__":
import sys
app = QtWidgets.QApplication(sys.argv)
Dialog = Dialog()
Dialog.show()
sys.exit(app.exec())