Exemplo n.º 1
0
 def __init__(self,parent=None):
     self.last_event_time = datetime.now()
     super(Calculator,self).__init__(parent=parent)
     self.ui = Ui_MainWindow()
     self.ui.setupUi(self)
     self.positive_float_validator = QtGui.QDoubleValidator(0,1e10,20)
     self.temperature_validator = QtGui.QDoubleValidator(-273.14,1000,20)
     self.unit_validator = QtGui.QDoubleValidator(0,1,20)
     
     self.ui.input1.setValidator(self.positive_float_validator)
     self.ui.input2.setValidator(self.temperature_validator)
     
     #set up connections
     self.ui.input_selector.currentIndexChanged.connect(
         self.input_properties_changed)
     self.ui.pushButton_calculate.clicked.connect(
         self.calculate_values)
     self.ui.delButton.clicked.connect(self.delRow)
     self.ui.clearButton.clicked.connect(self.clearTable)
     self.ui.actionExit.triggered.connect(QtGui.qApp.quit)
     self.ui.actionAbout.triggered.connect(self.show_about)
     self.ui.actionAbout_Qt.triggered.connect(lambda: QtGui.QMessageBox.aboutQt(self))
     
     self.initTable()
     self.calculate_values(None)
     self.show()
Exemplo n.º 2
0
class Calculator(QtGui.QMainWindow):
    
    def __init__(self,parent=None):
        self.last_event_time = datetime.now()
        super(Calculator,self).__init__(parent=parent)
        self.ui = Ui_MainWindow()
        self.ui.setupUi(self)
        self.positive_float_validator = QtGui.QDoubleValidator(0,1e10,20)
        self.temperature_validator = QtGui.QDoubleValidator(-273.14,1000,20)
        self.unit_validator = QtGui.QDoubleValidator(0,1,20)
        
        self.ui.input1.setValidator(self.positive_float_validator)
        self.ui.input2.setValidator(self.temperature_validator)
        
        #set up connections
        self.ui.input_selector.currentIndexChanged.connect(
            self.input_properties_changed)
        self.ui.pushButton_calculate.clicked.connect(
            self.calculate_values)
        self.ui.delButton.clicked.connect(self.delRow)
        self.ui.clearButton.clicked.connect(self.clearTable)
        self.ui.actionExit.triggered.connect(QtGui.qApp.quit)
        self.ui.actionAbout.triggered.connect(self.show_about)
        self.ui.actionAbout_Qt.triggered.connect(lambda: QtGui.QMessageBox.aboutQt(self))
        
        self.initTable()
        self.calculate_values(None)
        self.show()
    
    def initTable(self):
        self.ui.verticalLayout_2 = QtGui.QVBoxLayout(self.ui.scrollAreaWidgetContents)
        self.ui.verticalLayout_2.setObjectName("verticalLayout_2")
        
        self.waterTableModel = WaterTableModel(parent=self)
        self.table = QtGui.QTableView(parent=self)
        self.table.setModel(self.waterTableModel)
        self.table.setObjectName("table")
        self.table.resizeColumnsToContents()
        self.table.installEventFilter(self)
        self.ui.verticalLayout_2.addWidget(self.table)
        
    def input_properties_changed(self,e):
        ind = self.ui.input_selector.currentIndex()
        if len(self.waterTableModel.waterData) == 0:
            water = iapws(P=0.1,T=300.14)
        else:
            water = self.waterTableModel.waterData[-1]
            
        if ind < 4:
            input1 = "Pressure"
            input1_unit = "[bar]"
            self.ui.input1.setText("%g" %(water.P*10))
            self.ui.input1.setValidator(self.positive_float_validator)
            if ind == 0:
                input2 = "Temperature"
                input2_unit = "[C]"
                self.ui.input2.setText("%g" %(water.T-273.14))
                self.ui.input2.setValidator(self.temperature_validator)
            elif ind == 1:
                input2 = "Enthalpy"
                input2_unit = "[kJ/kg]"
                self.ui.input2.setText("%g" %water.h)
                self.ui.input2.setValidator(self.positive_float_validator)
            elif ind == 2:
                input2 = "Enthropy"
                input2_unit = "[kJ/kg K]"
                self.ui.input2.setText("%g" %water.s)
                self.ui.input2.setValidator(self.positive_float_validator)
            elif ind == 3:
                input2 = "Quality"
                input2_unit = "[-]"
                self.ui.input2.setText("%g" %water.x)
                self.ui.input2.setValidator(self.unit_validator)
        elif ind == 4:
            input1 = "Temperature"
            input1_unit = "[C]"
            self.ui.input1.setText("%g" %(water.T-273.14))
            self.ui.input1.setValidator(self.temperature_validator)
            input2 = "Quality"
            input2_unit = "[-]"
            self.ui.input2.setText("%g" %water.x)
            self.ui.input2.setValidator(self.unit_validator)
        elif ind == 5:
            input1 = "Enthalpy"
            input1_unit = "[kJ/kg]"
            self.ui.input1.setText("%g" %water.h)
            self.ui.input1.setValidator(self.positive_float_validator)
            input2 = "Enthropy"
            input2_unit = "[kJ/kg K]"
            self.ui.input2.setText("%g" %water.s)
            self.ui.input2.setValidator(self.positive_float_validator)
        self.ui.label_input1.setText(input1)
        self.ui.label_input1_unit.setText(input1_unit)
        self.ui.label_input2.setText(input2)
        self.ui.label_input2_unit.setText(input2_unit)
        
    def calculate_values(self,e):
        #toFloat returns tuple (value,status)
        input1 = self.ui.input1.text().toFloat()[0]
        input2 = self.ui.input2.text().toFloat()[0]
        self.calculate_values_from_input(input1,input2)
        self.table.resizeColumnsToContents()
        
    def calculate_values_from_input(self,input1,input2):
        ind = self.ui.input_selector.currentIndex()
        try:
            if ind < 4:
                input1 /= 10.0 #convert bar to MPa
                if ind == 0:
                    water = iapws(P=input1,T=input2+273.14)
                elif ind == 1:
                    water = iapws(P=input1,h=input2)
                elif ind == 2:
                    water = iapws(P=input1,s=input2)
                elif ind == 3:
                    water = iapws(P=input1,x=input2)
            elif ind == 4:
                water = iapws(T=input1+273.14,x=input2)
            elif ind == 5:
                water = iapws(h=input1,s=input2)
        except NotImplementedError:
            QtGui.QMessageBox.warning(self,"Bad input",
            "You've input bad values either out of bounds or not yet implemented.",
                                      QtGui.QMessageBox.NoButton,
                                      QtGui.QMessageBox.Ok,
                                      QtGui.QMessageBox.NoButton)
        #Don't update if values are bad
        if not water.status:
            return
        self.waterTableModel.addWater(water)
        
    def delRow(self):
        propsToDel = set()
        for index in self.table.selectedIndexes():
            propsToDel.add(index.row())
        self.waterTableModel.removeProps(propsToDel)

    def clearTable(self):
        numProps = self.waterTableModel.rowCount()
        self.waterTableModel.removeProps(range(numProps))
         
#        self.table.setColumnHidden(0,True)
    def show_about(self,e):
        msg = """
Calculator of water and steam properties.
GUI written by [email protected].

H2Oprops 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.

H2Oprops 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 H2Oprops.  If not, see <http://www.gnu.org/licenses/>.
        """
        QtGui.QMessageBox.about(self,"About H2Oprops",msg)

    def eventFilter(self,obj,event):
        if not event.__class__  == QtGui.QKeyEvent:
            return super(Calculator,self).eventFilter(obj,event)  

        if event.matches(QtGui.QKeySequence.Copy):
            if not self.handleEvent(): return True
            mime = self.tableToMimeData()
            QtGui.QApplication.clipboard().setMimeData(mime)
            
        elif event.matches(QtGui.QKeySequence.Paste):
            if not self.handleEvent(): return True
            self.pasteData()
        else:
            return super(Calculator,self).eventFilter(obj,event)  
        self.last_event_time = datetime.now()
        return True

    def handleEvent(self):
        now = datetime.now()
        time_diff = now - self.last_event_time
        total_time_diff = time_diff.seconds + time_diff.microseconds/1.0e6
        self.last_event_time = now 
        if total_time_diff < 0.5:
            return False
        return True
        
    def tableToMimeData(self):
        selectedCells = self.table.selectedIndexes()
        selRows=list()
        selCols=list()
        for cell in selectedCells:
            selRows.append(cell.row())
            selCols.append(cell.column())
        selRows=sorted(set(selRows))
        selCols=sorted(set(selCols))
        
        data = "<!--StartFragment-->\n"
        data += "<table>"
        data += "<tr>\n"
        for col in selCols:
            data += "  <td> " 
            data += self.waterTableModel.header[col][1]
            data += "</td>"
        data += "</tr>\n" 
        
        for row in selRows:
            data += "<tr>\n"
            water = self.waterTableModel.waterData[row]
            for col in selCols:
                data += " <td> "
                value = columnIdToPropertyValue(col,water)
                if value == -1:
                    data += "-"
                else:
                    data += "%g" %value
                data += " </td>\n"
            data += "</tr>\n"
        data += "</table>\n"
        data += "<!--EndFragment-->\n"
        
        mimeData = QtCore.QMimeData()
        mimeData.setHtml(data)
        return mimeData
    
    def pasteData(self):
        clip = QtGui.QApplication.clipboard()
        values = self.textToValues(str(clip.text()))
        if values.size ==0:
            return
        nrows,ncols = values.shape
        if nrows == 2 and ncols > 2:
            values = values.transpose()
            nrows,ncols = values.shape
        self.clearTable()
        for i in xrange(0,nrows):
            input1 = values[i,0]
            input2 = values[i,1]
            self.calculate_values_from_input(input1,input2)
        self.table.resizeColumnsToContents()
        
    def textToValues(self,text):
        values = np.fromstring(text,sep=" ")
        #figure out the shape of data
        lines = text.split("\n")
        try:
            lines.remove("")
        except ValueError:
            pass
        nrows = len(lines)
        ncols = len(lines[0].split())

        #validate data        
        if not values.dtype == float or \
                values[0] == -1 or \
                not (ncols ==2 or nrows == 2):
            msg = """
            Error pasted data must consist of 
            two columns where each column correspont
            to the selected variables in the input fields.
            For example:
            
            10 50
            10 60
            10 70

            and so on.
            """
            QtGui.QMessageBox.warning(self,"Bad clipboard",msg)
            return np.array([])
        
        #reshape vector to 2d matrix
        values = values.reshape(nrows,ncols)
        return values