source: sasview/src/sas/qtgui/Calculators/DensityPanel.py

ESS_GUI
Last change on this file was 33c0561, checked in by Piotr Rozyczko <piotr.rozyczko@…>, 6 years ago

Replace Apply button menu driven functionality with additional button.
Removed Cancel.
Removed the window system context help button from all affected widgets.
SASVIEW-1239

  • Property mode set to 100644
File size: 7.1 KB
RevLine 
[6083d6e]1# global
2import logging
[1d85b5e]3import functools
[4992ff2]4from PyQt5 import QtCore
5from PyQt5 import QtGui
6from PyQt5 import QtWidgets
[1d85b5e]7
[6083d6e]8from periodictable import formula as Formula
9
[83eb5208]10from sas.qtgui.Utilities.GuiUtils import FormulaValidator
[cd2cc745]11from sas.qtgui.UI import main_resources_rc
[b0c5e8c]12from sas.qtgui.Utilities.GuiUtils import HELP_DIRECTORY_LOCATION
[6083d6e]13
14# Local UI
[83eb5208]15from sas.qtgui.Calculators.UI.DensityPanel import Ui_DensityPanel
[6083d6e]16
[d4881f6a]17from sas.qtgui.Utilities.GuiUtils import enum
[d813cf9a]18from sas.qtgui.Utilities.GuiUtils import formatNumber
[6083d6e]19
20MODEL = enum(
21    'MOLECULAR_FORMULA',
22    'MOLAR_MASS',
23    'MOLAR_VOLUME',
24    'MASS_DENSITY',
25)
26
27MODES = enum(
28    'VOLUME_TO_DENSITY',
29    'DENSITY_TO_VOLUME',
30)
31
32def toMolarMass(formula):
33    AVOGADRO = 6.02214129e23
34
35    try:
36        f = Formula(str(formula))
37        return "%g" % (f.molecular_mass * AVOGADRO)
38    except:
39        return ""
40
41
[4992ff2]42class DensityPanel(QtWidgets.QDialog):
[6083d6e]43
44    def __init__(self, parent=None):
[1d85b5e]45        super(DensityPanel, self).__init__()
[6083d6e]46
47        self.mode = None
[1d85b5e]48        self.manager = parent
[6083d6e]49        self.setupUi()
[33c0561]50        # disable the context help icon
51        self.setWindowFlags(self.windowFlags() & ~QtCore.Qt.WindowContextHelpButtonHint)
52
[6083d6e]53        self.setupModel()
54        self.setupMapper()
55
56    def setupUi(self):
57        self.ui = Ui_DensityPanel()
58        self.ui.setupUi(self)
59
[b6f47be]60        #self.setFixedSize(self.minimumSizeHint())
61        self.resize(self.minimumSizeHint())
[f140169]62
[6083d6e]63        # set validators
[fbfc488]64        #self.ui.editMolecularFormula.setValidator(FormulaValidator(self.ui.editMolecularFormula))
[6083d6e]65
66        rx = QtCore.QRegExp("[+\-]?(?:0|[1-9]\d*)(?:\.\d*)?(?:[eE][+\-]?\d+)?")
67        self.ui.editMolarVolume.setValidator(QtGui.QRegExpValidator(rx, self.ui.editMolarVolume))
68        self.ui.editMassDensity.setValidator(QtGui.QRegExpValidator(rx, self.ui.editMassDensity))
69
70        # signals
[1d85b5e]71        self.ui.editMolarVolume.textEdited.connect(functools.partial(self.setMode, MODES.VOLUME_TO_DENSITY))
72        self.ui.editMassDensity.textEdited.connect(functools.partial(self.setMode, MODES.DENSITY_TO_VOLUME))
73
[4992ff2]74        self.ui.buttonBox.button(QtWidgets.QDialogButtonBox.Reset).clicked.connect(self.modelReset)
75        self.ui.buttonBox.button(QtWidgets.QDialogButtonBox.Help).clicked.connect(self.displayHelp)
[6083d6e]76
77    def setupModel(self):
78        self.model = QtGui.QStandardItemModel(self)
79        self.model.setItem(MODEL.MOLECULAR_FORMULA, QtGui.QStandardItem())
80        self.model.setItem(MODEL.MOLAR_MASS       , QtGui.QStandardItem())
81        self.model.setItem(MODEL.MOLAR_VOLUME     , QtGui.QStandardItem())
82        self.model.setItem(MODEL.MASS_DENSITY     , QtGui.QStandardItem())
83
[1d85b5e]84        self.model.dataChanged.connect(self.dataChanged)
[6083d6e]85
[51b9c14]86        self.ui.editMolarVolume.textEdited.connect(self.volumeChanged)
87        self.ui.editMassDensity.textEdited.connect(self.massChanged)
88        self.ui.editMolecularFormula.textEdited.connect(self.formulaChanged)
89
[6083d6e]90        self.modelReset()
91
92    def setupMapper(self):
[4992ff2]93        self.mapper = QtWidgets.QDataWidgetMapper(self)
[6083d6e]94        self.mapper.setModel(self.model)
95        self.mapper.setOrientation(QtCore.Qt.Vertical)
96
97        self.mapper.addMapping(self.ui.editMolecularFormula, MODEL.MOLECULAR_FORMULA)
98        self.mapper.addMapping(self.ui.editMolarMass       , MODEL.MOLAR_MASS)
99        self.mapper.addMapping(self.ui.editMolarVolume     , MODEL.MOLAR_VOLUME)
100        self.mapper.addMapping(self.ui.editMassDensity     , MODEL.MASS_DENSITY)
101
[fbfc488]102        self.mapper.toFirst()
[6083d6e]103
104    def dataChanged(self, top, bottom):
[b3e8629]105        for index in range(top.row(), bottom.row() + 1):
[6083d6e]106            if index == MODEL.MOLECULAR_FORMULA:
107                molarMass = toMolarMass(self.model.item(MODEL.MOLECULAR_FORMULA).text())
[d813cf9a]108                molarMass = formatNumber(molarMass, high=True)
[6083d6e]109                self.model.item(MODEL.MOLAR_MASS).setText(molarMass)
110
111                if self.mode == MODES.VOLUME_TO_DENSITY:
112                    self._updateDensity()
113                elif self.mode == MODES.DENSITY_TO_VOLUME:
114                    self._updateVolume()
115
116            elif index == MODEL.MOLAR_VOLUME and self.mode == MODES.VOLUME_TO_DENSITY:
117                self._updateDensity()
118
119            elif index == MODEL.MASS_DENSITY and self.mode == MODES.DENSITY_TO_VOLUME:
120                self._updateVolume()
121
[51b9c14]122    def volumeChanged(self, current_text):
123        try:
124            molarMass = float(toMolarMass(self.model.item(MODEL.MOLECULAR_FORMULA).text()))
125            molarVolume = float(current_text)
126
127            molarDensity = molarMass / molarVolume
128            molarDensity = formatNumber(molarDensity, high=True)
129            self.model.item(MODEL.MASS_DENSITY).setText(str(molarDensity))
130
131        except (ArithmeticError, ValueError):
132            self.model.item(MODEL.MASS_DENSITY).setText("")
133
134    def massChanged(self, current_text):
135        try:
136            molarMass = float(toMolarMass(self.model.item(MODEL.MOLECULAR_FORMULA).text()))
137            molarDensity = float(current_text)
138
139            molarVolume = molarMass / molarDensity
140            molarVolume = formatNumber(molarVolume, high=True)
141            self.model.item(MODEL.MOLAR_VOLUME).setText(str(molarVolume))
142
143        except (ArithmeticError, ValueError):
144            self.model.item(MODEL.MOLAR_VOLUME).setText("")
145
146    def formulaChanged(self, current_text):
147        try:
148            molarMass = toMolarMass(current_text)
[b6f47be]149            # if this doesn't fail, update the model item for formula
150            # so related values can get recomputed
151            self.model.item(MODEL.MOLECULAR_FORMULA).setText(current_text)
[51b9c14]152
153        except (ArithmeticError, ValueError):
154            self.model.item(MODEL.MOLAR_VOLUME).setText("")
155
[6083d6e]156    def setMode(self, mode):
157        self.mode = mode
158
159    def _updateDensity(self):
160        try:
161            molarMass = float(toMolarMass(self.model.item(MODEL.MOLECULAR_FORMULA).text()))
162            molarVolume = float(self.model.item(MODEL.MOLAR_VOLUME).text())
163
164            molarDensity = molarMass / molarVolume
[d813cf9a]165            molarDensity = formatNumber(molarDensity, high=True)
[6083d6e]166            self.model.item(MODEL.MASS_DENSITY).setText(str(molarDensity))
167
[9968d6a]168        except (ArithmeticError, ValueError):
[6083d6e]169            self.model.item(MODEL.MASS_DENSITY).setText("")
170
171    def _updateVolume(self):
172        try:
173            molarMass = float(toMolarMass(self.model.item(MODEL.MOLECULAR_FORMULA).text()))
174            molarDensity = float(self.model.item(MODEL.MASS_DENSITY).text())
175
176            molarVolume = molarMass / molarDensity
[d813cf9a]177            molarVolume = formatNumber(molarVolume, high=True)
[6083d6e]178            self.model.item(MODEL.MOLAR_VOLUME).setText(str(molarVolume))
179
[9968d6a]180        except (ArithmeticError, ValueError):
[6083d6e]181            self.model.item(MODEL.MOLAR_VOLUME).setText("")
182
183    def modelReset(self):
184        try:
185            self.setMode(None)
186            self.model.item(MODEL.MOLECULAR_FORMULA).setText("H2O")
187            self.model.item(MODEL.MOLAR_VOLUME     ).setText("")
188            self.model.item(MODEL.MASS_DENSITY     ).setText("")
189        finally:
190            pass
[1d85b5e]191
192    def displayHelp(self):
[aed0532]193        location = "/user/qtgui/Calculators/density_calculator_help.html"
[e90988c]194        self.manager.showHelp(location)
195
[9968d6a]196
Note: See TracBrowser for help on using the repository browser.