Created
November 22, 2019 10:18
-
-
Save DragonOsman/ba1ec3e5b60909e41a2b378a911490f9 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <QtWidgets/qgridlayout.h> | |
#include <QtWidgets/qtoolbutton.h> | |
#include <cmath> | |
#include "Button.h" | |
Calculator::Calculator(QWidget* parent) | |
: QWidget(parent) | |
{ | |
sumInMemory = 0.0; | |
sumSoFar = 0.0; | |
factorSoFar = 0.0; | |
waitingForOperand = true; | |
display = new QLineEdit("0"); | |
display->setReadOnly(true); | |
display->setAlignment(Qt::AlignRight); | |
display->setMaxLength(15); | |
QFont font = display->font(); | |
font.setPointSize(font.pointSize() + 8); | |
display->setFont(font); | |
for (std::size_t i{}; i < NumDigitButtons; ++i) { | |
digitButtons[i] = createButton(QString::number(i), SLOT(digitClicked())); | |
} | |
Button* pointButton{ createButton(tr("."), SLOT(pointClicked())) }; | |
Button* changeSignButton{ createButton(tr("\302\261"), SLOT(changeSignClicked())) }; | |
Button* backspaceButton{ createButton(tr("Backspace"), SLOT(backspaceClicked())) }; | |
Button* clearButton{ createButton(tr("Clear"), SLOT(clear())) }; | |
Button* clearAllButton{ createButton(tr("Clear All"), SLOT(clearAll())) }; | |
Button* clearMemoryButton{ createButton(tr("MC"), SLOT(clearMemory())) }; | |
Button* readMemoryButton{ createButton(tr("MR"), SLOT(readMemory())) }; | |
Button* setMemoryButton{ createButton(tr("MS"), SLOT(setMemory())) }; | |
Button* addToMemoryButton{ createButton(tr("M+"), SLOT(addToMemory())) }; | |
Button* divisionButton{ createButton(tr("\303\267"), SLOT(multiplicativeOperatorClicked())) }; | |
Button* timesButton{ createButton(tr("\303\227"), SLOT(multiplicativeOperatorClicked())) }; | |
Button* minusButton{ createButton(tr("-"), SLOT(additiveOperatorClicked())) }; | |
Button* plusButton{ createButton(tr("+"), SLOT(additiveOperatorClicked())) }; | |
Button* squareRootButton{ createButton(tr("Sqrt"), SLOT(unaryOperatorClicked())) }; | |
Button* powerButton{ createButton(tr("x\302\262"), SLOT(unaryOperatorClicked())) }; | |
Button* reciprocalButton{ createButton(tr("1/x"), SLOT(unaryOperatorClicked())) }; | |
Button* equalButton{ createButton(tr("="), SLOT(equalClicked())) }; | |
QGridLayout* mainLayout{ new QGridLayout }; | |
mainLayout->setSizeConstraint(QLayout::SetFixedSize); | |
mainLayout->addWidget(display, 0, 0, 1, 6); | |
mainLayout->addWidget(backspaceButton, 1, 0, 1, 2); | |
mainLayout->addWidget(clearButton, 1, 2, 1, 2); | |
mainLayout->addWidget(clearAllButton, 1, 4, 1, 2); | |
mainLayout->addWidget(clearMemoryButton, 2, 0); | |
mainLayout->addWidget(readMemoryButton, 3, 0); | |
mainLayout->addWidget(setMemoryButton, 4, 0); | |
mainLayout->addWidget(addToMemoryButton, 5, 0); | |
for (std::size_t i{ 1 }; i < NumDigitButtons; ++i) { | |
int row = ((9 - i) / 3) + 2; | |
int column = ((i - 1) % 3) + 1; | |
mainLayout->addWidget(digitButtons[i], row, column); | |
} | |
mainLayout->addWidget(digitButtons[0], 5, 1); | |
mainLayout->addWidget(pointButton, 5, 2); | |
mainLayout->addWidget(changeSignButton, 5, 3); | |
mainLayout->addWidget(divisionButton, 2, 4); | |
mainLayout->addWidget(timesButton, 3, 4); | |
mainLayout->addWidget(minusButton, 4, 4); | |
mainLayout->addWidget(plusButton, 5, 4); | |
mainLayout->addWidget(squareRootButton, 2, 5); | |
mainLayout->addWidget(powerButton, 3, 5); | |
mainLayout->addWidget(reciprocalButton, 4, 5); | |
mainLayout->addWidget(equalButton, 5, 5); | |
setLayout(mainLayout); | |
setWindowTitle(tr("Calculator")); | |
} | |
void Calculator::digitClicked() | |
{ | |
Button* clickedButton{ qobject_cast<Button*>(sender()) }; | |
int digitValue{ clickedButton->text().toInt() }; | |
if (display->text() == "0" && digitValue == 0.0) | |
{ | |
return; | |
} | |
if (waitingForOperand) | |
{ | |
display->clear(); | |
waitingForOperand = false; | |
} | |
display->setText(display->text() + QString::number(digitValue)); | |
} | |
void Calculator::unaryOperatorClicked() | |
{ | |
Button* clickedButton{ qobject_cast<Button*>(sender()) }; | |
QString clickedOperator{ clickedButton->text() }; | |
double operand{ display->text().toDouble() }; | |
double result{}; | |
if (clickedOperator == tr("Sqrt")) | |
{ | |
if (operand < 0.0) | |
{ | |
abortOperation(); | |
return; | |
} | |
result = std::sqrt(operand); | |
} | |
else if (clickedOperator == tr("x\302\262")) | |
{ | |
result = std::pow(operand, 2.0); | |
} | |
else if (clickedOperator == tr("1/x")) | |
{ | |
if (operand == 0.0) | |
{ | |
abortOperation(); | |
return; | |
} | |
result = 1.0 / operand; | |
} | |
display->setText(QString::number(result)); | |
waitingForOperand = true; | |
} | |
void Calculator::additiveOperatorClicked() | |
{ | |
Button* clickedButton{ qobject_cast<Button*>(sender()) }; | |
QString clickedOperator{ clickedButton->text() }; | |
double operand{ display->text().toDouble() }; | |
if (!pendingMultiplicativeOperator.isEmpty()) | |
{ | |
if (!calculate(operand, pendingMultiplicativeOperator)) | |
{ | |
abortOperation(); | |
return; | |
} | |
display->setText(QString::number(factorSoFar)); | |
operand = factorSoFar; | |
factorSoFar = 0.0; | |
pendingMultiplicativeOperator.clear(); | |
} | |
if (!pendingAdditiveOperator.isEmpty()) | |
{ | |
if (!calculate(operand, pendingAdditiveOperator)) | |
{ | |
abortOperation(); | |
return; | |
} | |
display->setText(QString::number(sumSoFar)); | |
} | |
else | |
{ | |
sumSoFar = operand; | |
} | |
pendingAdditiveOperator = clickedOperator; | |
waitingForOperand = true; | |
} | |
void Calculator::multiplicativeOpteratorClicked() | |
{ | |
Button* clickedButton{ qobject_cast<Button*>(sender()) }; | |
QString clickedOperator{ clickedButton->text() }; | |
double operand{ display->text().toDouble() }; | |
if (!pendingMultiplicativeOperator.isEmpty()) | |
{ | |
if (!calculate(operand, pendingMultiplicativeOperator)) | |
{ | |
abortOperation(); | |
return; | |
} | |
display->setText(QString::number(factorSoFar)); | |
} | |
else | |
{ | |
factorSoFar = operand; | |
} | |
pendingMultiplicativeOperator = clickedOperator; | |
waitingForOperand = true; | |
} | |
void Calculator::equalClicked() | |
{ | |
double operand{ display->text().toDouble() }; | |
if (!pendingMultiplicativeOperator.isEmpty()) | |
{ | |
if (!calculate(operand, pendingMultiplicativeOperator)) | |
{ | |
abortOperation(); | |
return; | |
} | |
operand = factorSoFar; | |
factorSoFar = 0.0; | |
pendingMultiplicativeOperator.clear(); | |
} | |
if (!pendingAdditiveOperator.isEmpty()) | |
{ | |
if (!calculate(operand, pendingAdditiveOperator)) | |
{ | |
abortOperation(); | |
return; | |
} | |
pendingAdditiveOperator.clear(); | |
} | |
else | |
{ | |
sumSoFar = operand; | |
} | |
display->setText(QString::number(sumSoFar)); | |
sumSoFar = 0.0; | |
waitingForOperand = true; | |
} | |
void Calculator::pointClicked() | |
{ | |
if (waitingForOperand) | |
{ | |
display->setText("0"); | |
} | |
if (!display->text().contains(".")) | |
{ | |
display->setText(display->text() + tr(".")); | |
} | |
waitingForOperand = false; | |
} | |
void Calculator::changeSignClicked() | |
{ | |
QString text{ display->text() }; | |
double value{ text.toDouble() }; | |
if (value > 0.0) | |
{ | |
text.prepend(tr("-")); | |
} | |
else if (value < 0.0) | |
{ | |
text.remove(0, 1); | |
} | |
display->setText(text); | |
} | |
void Calculator::backspaceClicked() | |
{ | |
if (waitingForOperand) | |
{ | |
return; | |
} | |
QString text{ display->text() }; | |
text.chop(1); | |
if (text.isEmpty()) | |
{ | |
text = "0"; | |
waitingForOperand = true; | |
} | |
display->setText(text); | |
} | |
void Calculator::clear() | |
{ | |
if (waitingForOperand) | |
{ | |
return; | |
} | |
display->setText("0"); | |
waitingForOperand = true; | |
} | |
void Calculator::clearAll() | |
{ | |
sumSoFar = 0.0; | |
factorSoFar = 0.0; | |
pendingAdditiveOperator.clear(); | |
pendingMultiplicativeOperator.clear(); | |
display->setText("0"); | |
waitingForOperand = true; | |
} | |
void Calculator::clearMemory() | |
{ | |
sumInMemory = 0.0; | |
} | |
void Calculator::readMemory() | |
{ | |
display->setText(QString::number(sumInMemory)); | |
waitingForOperand = true; | |
} | |
void Calculator::setMemory() | |
{ | |
equalClicked(); | |
sumInMemory = display->text().toDouble(); | |
} | |
void Calculator::addToMemory() | |
{ | |
equalClicked(); | |
sumInMemory += display->text().toDouble(); | |
} | |
Button* Calculator::createButton(const QString& text, const char* member) | |
{ | |
Button* button{ new Button(text) }; | |
connect(button, SIGNAL(clicked), this, member); | |
return button; | |
} | |
void Calculator::abortOperation() | |
{ | |
clearAll(); | |
display->setText(tr("####")); | |
} | |
bool Calculator::calculate(double rightOperand, const QString& pendingOperator) | |
{ | |
if (pendingOperator == tr("+")) | |
{ | |
sumSoFar += rightOperand; | |
} | |
else if (pendingOperator == tr("-")) | |
{ | |
sumSoFar -= rightOperand; | |
} | |
else if (pendingOperator == tr("\303\227")) | |
{ | |
factorSoFar *= rightOperand; | |
} | |
else if (pendingOperator == tr("\303\267")) | |
{ | |
if (rightOperand == 0.0) | |
{ | |
return false; | |
} | |
factorSoFar /= rightOperand; | |
} | |
return true; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#ifndef CALCULATOR_H | |
#define CALCULATOR_H | |
#include <QtWidgets/qwidget.h> | |
#include <QtWidgets/qlineedit.h> | |
#include "Button.h" | |
class Calculator : public QWidget | |
{ | |
Q_OBJECT | |
public: | |
Calculator(QWidget* parent = nullptr); | |
private slots: | |
void digitClicked(); | |
void unaryOperatorClicked(); | |
void additiveOperatorClicked(); | |
void multiplicativeOpteratorClicked(); | |
void equalClicked(); | |
void pointClicked(); | |
void changeSignClicked(); | |
void backspaceClicked(); | |
void clear(); | |
void clearAll(); | |
void clearMemory(); | |
void readMemory(); | |
void setMemory(); | |
void addToMemory(); | |
private: | |
Button* createButton(const QString& text, const char* member); | |
void abortOperation(); | |
bool calculate(const double rightOperand, const QString& pendingOperator); | |
double sumInMemory; | |
double sumSoFar; | |
double factorSoFar; | |
QString pendingAdditiveOperator; | |
QString pendingMultiplicativeOperator; | |
bool waitingForOperand; | |
QLineEdit* display; | |
enum { NumDigitButtons = 10 }; | |
Button* digitButtons[NumDigitButtons]; | |
}; | |
#endif |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Osman Zakir | |
// 11 / 19 / 2019 | |
// Qt Calculator App | |
// I made this app following the Qt Calculator Example. | |
#include <QtWidgets/qapplication.h> | |
#include "Calculator.h" | |
int main(int argc, char* argv[]) | |
{ | |
QApplication app{ argc, argv }; | |
Calculator calc; | |
calc.show(); | |
return app.exec(); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment