#!/usr/bin/env python
################################################################################
#
# qooxdoo – the new era of web development
#
# http://qooxdoo.org
#
# Copyright:
# 2006-2008 1&1 Internet AG, Germany, http://www.1und1.de
#
# License:
# LGPL: http://www.gnu.org/licenses/lgpl.html
# EPL: http://www.eclipse.org/org/documents/epl-v10.php
# See the LICENSE file in the project’s top-level directory for details.
#
# Authors:
# * Thomas Herchenroeder (thron7)
#
################################################################################
import sys
import math
from PyQt4 import QtCore, QtGui
class Button(QtGui.QToolButton):
def __init__(self, text, color, parent=None):
QtGui.QToolButton.__init__(self, parent)
self.setSizePolicy(QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Preferred)
self.setText(text)
newPalette = self.palette()
newPalette.setColor(QtGui.QPalette.Button, color)
self.setPalette(newPalette)
def sizeHint(self):
size = QtGui.QToolButton.sizeHint(self)
size.setHeight(size.height() + 20)
size.setWidth(max(size.width(), size.height()))
return size
class Calculator(QtGui.QDialog):
NumDigitButtons = 10
def __init__(self, parent=None):
QtGui.QDialog.__init__(self, parent)
self.pendingAdditiveOperator = QtCore.QString()
self.pendingMultiplicativeOperator = QtCore.QString()
self.sumInMemory = 0.0
self.sumSoFar = 0.0
self.factorSoFar = 0.0
self.waitingForOperand = True
self.display = QtGui.QLineEdit(“0″)
self.display.setReadOnly(True)
self.display.setAlignment(QtCore.Qt.AlignRight)
self.display.setMaxLength(15)
self.display.installEventFilter(self)
font = self.display.font()
font.setPointSize(font.pointSize() + 8)
self.display.setFont(font)
digitColor = QtGui.QColor(150, 205, 205)
backspaceColor = QtGui.QColor(225, 185, 135)
memoryColor = QtGui.QColor(100, 155, 155)
operatorColor = QtGui.QColor(155, 175, 195)
self.digitButtons = []
for i in range(Calculator.NumDigitButtons):
self.digitButtons.append(self.createButton(QtCore.QString.number(i),
digitColor,
self.digitClicked))
self.pointButton = self.createButton(self.tr(“.”), digitColor,
self.pointClicked)
self.changeSignButton = self.createButton(self.tr(“\261″), digitColor,
self.changeSignClicked)
self.backspaceButton = self.createButton(self.tr(“Backspace”),
backspaceColor,
self.backspaceClicked)
self.clearButton = self.createButton(self.tr(“Clear”), backspaceColor,
self.clear)
self.clearAllButton = self.createButton(self.tr(“Clear All”),
backspaceColor.light(120),
self.clearAll)
self.clearMemoryButton = self.createButton(self.tr(“MC”), memoryColor,
self.clearMemory)
self.readMemoryButton = self.createButton(self.tr(“MR”), memoryColor,
self.readMemory)
self.setMemoryButton = self.createButton(self.tr(“MS”), memoryColor,
self.setMemory)
self.addToMemoryButton = self.createButton(self.tr(“M+”), memoryColor,
self.addToMemory)
self.divisionButton = self.createButton(self.tr(“\367″), operatorColor,
self.multiplicativeOperatorClicked)
self.timesButton = self.createButton(self.tr(“\327″), operatorColor,
self.multiplicativeOperatorClicked)
self.minusButton = self.createButton(self.tr(“-”), operatorColor,
self.additiveOperatorClicked)
self.plusButton = self.createButton(self.tr(“+”), operatorColor,
self.additiveOperatorClicked)
self.squareRootButton = self.createButton(self.tr(“Sqrt”),
operatorColor,
self.unaryOperatorClicked)
self.powerButton = self.createButton(self.tr(“x\262″), operatorColor,
self.unaryOperatorClicked)
self.reciprocalButton = self.createButton(self.tr(“1/x”), operatorColor,
self.unaryOperatorClicked)
self.equalButton = self.createButton(self.tr(“=”),
operatorColor.light(120),
self.equalClicked)
mainLayout = QtGui.QGridLayout()
mainLayout.setSizeConstraint(QtGui.QLayout.SetFixedSize)
mainLayout.addWidget(self.display, 0, 0, 1, 6)
mainLayout.addWidget(self.backspaceButton, 1, 0, 1, 2)
mainLayout.addWidget(self.clearButton, 1, 2, 1, 2)
mainLayout.addWidget(self.clearAllButton, 1, 4, 1, 2)
mainLayout.addWidget(self.clearMemoryButton, 2, 0)
mainLayout.addWidget(self.readMemoryButton, 3, 0)
mainLayout.addWidget(self.setMemoryButton, 4, 0)
mainLayout.addWidget(self.addToMemoryButton, 5, 0)
for i in range(1, Calculator.NumDigitButtons):
row = ((9 – i) / 3) + 2
column = ((i – 1) % 3) + 1
mainLayout.addWidget(self.digitButtons[i], row, column)
mainLayout.addWidget(self.digitButtons[0], 5, 1)
mainLayout.addWidget(self.pointButton, 5, 2)
mainLayout.addWidget(self.changeSignButton, 5, 3)
mainLayout.addWidget(self.divisionButton, 2, 4)
mainLayout.addWidget(self.timesButton, 3, 4)
mainLayout.addWidget(self.minusButton, 4, 4)
mainLayout.addWidget(self.plusButton, 5, 4)
mainLayout.addWidget(self.squareRootButton, 2, 5)
mainLayout.addWidget(self.powerButton, 3, 5)
mainLayout.addWidget(self.reciprocalButton, 4, 5)
mainLayout.addWidget(self.equalButton, 5, 5)
self.setLayout(mainLayout)
self.setWindowTitle(self.tr(“Calculator”))
def eventFilter(self, target, event):
if target == self.display:
if (event.type() == QtCore.QEvent.MouseButtonPress or
event.type() == QtCore.QEvent.MouseButtonDblClick or
event.type() == QtCore.QEvent.MouseButtonRelease or
event.type() == QtCore.QEvent.ContextMenu):
if mouseEvent.buttons() & QtCore.Qt.LeftButton:
newPalette = self.palette()
newPalette.setColor(QtGui.QPalette.Base,
self.display.palette().color(QtGui.QPalette.Text))
newPalette.setColor(QtGui.QPalette.Text,
self.display.palette().color(QtGui.QPalette.Base))
self.display.setPalette(newPalette)
else:
self.display.setPalette(palette())
return True
return QtGui.QDialog.eventFilter(self, target, event)
def digitClicked(self):
clickedButton = self.sender()
digitValue, success = clickedButton.text().toInt()
if self.display.text() == “0″ and digitValue == 0.0:
return
if self.waitingForOperand:
self.display.clear()
self.waitingForOperand = False
self.display.setText(self.display.text() + QtCore.QString.number(digitValue))
def unaryOperatorClicked(self):
clickedButton = self.sender()
clickedOperator = clickedButton.text()
operand, success = self.display.text().toDouble()
if clickedOperator == self.tr(“Sqrt”):
if operand < 0.0:
self.abortOperation()
return
result = math.sqrt(operand)
elif clickedOperator == self.tr(“x\262″):
result = math.pow(operand, 2.0)
elif clickedOperator == self.tr(“1/x”):
if operand == 0.0:
self.abortOperation()
return
result = 1.0 / operand
self.display.setText(QtCore.QString.number(result))
self.waitingForOperand = True
def additiveOperatorClicked(self):
clickedButton = self.sender()
clickedOperator = clickedButton.text()
operand, success = self.display.text().toDouble()
if not self.pendingMultiplicativeOperator.isEmpty():
if not self.calculate(operand, self.pendingMultiplicativeOperator):
self.abortOperation()
return
self.display.setText(QtCore.QString.number(self.factorSoFar))
operand = self.factorSoFar
self.factorSoFar = 0.0
self.pendingMultiplicativeOperator.clear()
if not self.pendingAdditiveOperator.isEmpty():
if not self.calculate(operand, self.pendingAdditiveOperator):
self.abortOperation()
return
self.display.setText(QtCore.QString.number(self.sumSoFar))
else:
self.sumSoFar = operand
self.pendingAdditiveOperator = clickedOperator
self.waitingForOperand = True
def multiplicativeOperatorClicked(self):
clickedButton = self.sender()
clickedOperator = clickedButton.text()
operand, success = self.display.text().toDouble()
if not self.pendingMultiplicativeOperator.isEmpty():
if not self.calculate(operand, self.pendingMultiplicativeOperator):
self.abortOperation()
return
self.display.setText(QtCore.QString.number(self.factorSoFar))
else:
self.factorSoFar = operand
self.pendingMultiplicativeOperator = clickedOperator
self.waitingForOperand = True
def equalClicked(self):
operand, success = self.display.text().toDouble()
if not self.pendingMultiplicativeOperator.isEmpty():
if not self.calculate(operand, self.pendingMultiplicativeOperator):
self.abortOperation()
return
operand = self.factorSoFar
self.factorSoFar = 0.0
self.pendingMultiplicativeOperator.clear()
if not self.pendingAdditiveOperator.isEmpty():
if not self.calculate(operand, self.pendingAdditiveOperator):
self.abortOperation()
return
self.pendingAdditiveOperator.clear()
else:
self.sumSoFar = operand
self.display.setText(QtCore.QString.number(self.sumSoFar))
self.sumSoFar = 0.0
self.waitingForOperand = True
def pointClicked(self):
if self.waitingForOperand:
self.display.setText(“0″)
if not self.display.text().contains(“.”):
self.display.setText(self.display.text() + self.tr(“.”))
self.waitingForOperand = False
def changeSignClicked(self):
text = self.display.text()
value, success = text.toDouble()
if value > 0.0:
text.prepend(self.tr(“-”))
elif value < 0.0:
text.remove(0, 1)
self.display.setText(text)
def backspaceClicked(self):
if self.waitingForOperand:
return
text = self.display.text()
text.chop(1)
if text.isEmpty():
text = “0″
self.waitingForOperand = True
self.display.setText(text)
def clear(self):
if self.waitingForOperand:
return
self.display.setText(“0″)
self.waitingForOperand = True
def clearAll(self):
self.sumSoFar = 0.0
self.factorSoFar = 0.0
self.pendingAdditiveOperator.clear()
self.pendingMultiplicativeOperator.clear()
self.display.setText(“0″)
self.waitingForOperand = True
def clearMemory(self):
self.sumInMemory = 0.0
def readMemory(self):
self.display.setText(QtCore.QString.number(self.sumInMemory))
self.waitingForOperand = True
def setMemory(self):
self.equalClicked()
self.sumInMemory, success = self.display.text().toDouble()
def addToMemory(self):
self.equalClicked()
value, success = self.display.text().toDouble()
self.sumInMemory += value
def createButton(self, text, color, member):
button = Button(text, color)
self.connect(button, QtCore.SIGNAL(“clicked()”), member)
return button
def abortOperation(self):
self.clearAll()
self.display.setText(self.tr(“####”))
def calculate(self, rightOperand, pendingOperator):
if pendingOperator == self.tr(“+”):
self.sumSoFar += rightOperand
elif pendingOperator == self.tr(“-”):
self.sumSoFar -= rightOperand
elif pendingOperator == self.tr(“\327″):
self.factorSoFar *= rightOperand
elif pendingOperator == self.tr(“\367″):
if rightOperand == 0.0:
return False
self.factorSoFar /= rightOperand
return True
if __name__ == “__main__”:
app = QtGui.QApplication(sys.argv)
calc = Calculator()
sys.exit(calc.exec_())