vs集積qtは簡単な計算機を実現する
すべての状況を考慮していないかもしれませんが、基本的な計算はできます!
Calculator.h
Calculaor.cpp
calculation.h
calculation.cpp
リンク:https://share.weiyun.com/5A45cgb
画像の素材はリンクの中にあって、マイクロソフトのコンピュータのスクリーンショットです
Calculator.h
#pragma once
#include
#include "ui_Calculator.h"
#include "calculation.h"
#include
#include
#include
#include
const int TOTALNUM = 10; //
const int OPERATORNUM = 6; //
const int WIDTH = 300; //
const int HEIGHT = 450; //
const int ZOOMINWIDTH = 600; //
const int BUTTONWIDTH = 60; //
const int BUTTONHEIGHT = 40; //
const int SMALLBUTTONWIDTH = 30; //
const int SMALLBUTTONHEIGHT = 30; //
class Calculator : public QDialog
{
Q_OBJECT
public:
Calculator(QWidget *parent = Q_NULLPTR);
private:
Ui::CalculatorClass ui;
private:
calculation c;
QPushButton *histotyButton;
QPushButton *numButton[TOTALNUM];
QPushButton *operatorButton[OPERATORNUM];
QPushButton *pointButton;
QPushButton *leftParenthesesButton;
QPushButton *rightParenthesesButton;
QPushButton *sinButton;
QPushButton *cosButton;
QPushButton *tanButton;
QPushButton *sqrtButton;
QPushButton *squareButton;
QPushButton *logButton;
QPushButton *expButton;
QPushButton *none1;
QPushButton *none2;
QPushButton *miciButton;
QPushButton *tenMiciButton;
QPushButton *factorialButton;
QPushButton *positiveAndNegativeButton;
QPushButton *piButton;
QPushButton *clearButton;
QPushButton *backspaceButton;
QLineEdit *expressionLineEdit;
QPlainTextEdit *historyResultTextEdit;
private:
void initButton();
void setButton(QPushButton * button, const QString & filePath, const int & width, const int & height, const int & buttonWidth = BUTTONWIDTH, const int & buttonHeight = BUTTONHEIGHT);
void initLineEdit();
char* getLastNum();
private slots:
void onNumButtonClicked(const qreal & num);
void onOperatorButtonClicked(const char & operatorName);
void backspaceButtonClicked();
void clearButtonClicked();
void triFunButtonClicked(const QString & tri);
void squareButtonClicked();
void sqrtButtonClicked();
void powButtonClicked();
void tenPowButtonClicked();
void positiveAndNegativeButtonClicked();
void eFunButtonClicked(const QString & e);
void histotyButtonClicked();
};
Calculaor.cpp
#include "Calculator.h"
bool zoomin = false; // ( )
const char OPERATOR[] = "%/*-+=";
Calculator::Calculator(QWidget *parent)
: QDialog(parent)
{
ui.setupUi(this);
//
initButton();
initLineEdit();
}
//
double factorial(int n) {
double res = 1;
while (n > 0) {
res *= n;
n--;
}
return res;
}
void Calculator::initButton()
{
setMinimumSize(WIDTH, HEIGHT);
setMaximumSize(WIDTH, HEIGHT);
QString iconPath;
int j = 1;
int i;
//
for (i = 0; i < TOTALNUM; ++i) {
numButton[i] = new QPushButton(this);
iconPath = "./img/num" + QString::number(i) + ".png";
if (i == 0) {
setButton(numButton[i], iconPath, (WIDTH - BUTTONWIDTH) >> 1, HEIGHT - BUTTONHEIGHT);
}
else {
if (i % 3 == 1) {
j++;
}
setButton(numButton[i], iconPath, BUTTONWIDTH * ((i - 1) % 3 + 1), HEIGHT - j * BUTTONHEIGHT);
}
// lamda
connect(numButton[i], &QPushButton::clicked, this, [=] {onNumButtonClicked(i); });
}
//
for (i = 0; i < OPERATORNUM; ++i) {
operatorButton[i] = new QPushButton(this);
iconPath = "./img/operator" + QString::number(i + 1) + ".png";
setButton(operatorButton[i], iconPath, WIDTH - BUTTONWIDTH, HEIGHT - BUTTONHEIGHT * (OPERATORNUM - i));
connect(operatorButton[i], &QPushButton::clicked, this, [=] {onOperatorButtonClicked(OPERATOR[i]); });
}
//
pointButton = new QPushButton(this);
setButton(pointButton, "./img/point.png", WIDTH - BUTTONWIDTH * 2, HEIGHT - BUTTONHEIGHT);
connect(pointButton, &QPushButton::clicked, this, [=] {onOperatorButtonClicked('.'); });
//
leftParenthesesButton = new QPushButton(this);
setButton(leftParenthesesButton, "./img/leftParentheses.png", 0, HEIGHT - BUTTONHEIGHT);
connect(leftParenthesesButton, &QPushButton::clicked, this, [=] {onOperatorButtonClicked('('); });
//
rightParenthesesButton = new QPushButton(this);
setButton(rightParenthesesButton, "./img/rightParentheses.png", BUTTONWIDTH, HEIGHT - BUTTONHEIGHT);
connect(rightParenthesesButton, &QPushButton::clicked, this, [=] {onOperatorButtonClicked(')'); });
//
sinButton = new QPushButton(this);
cosButton = new QPushButton(this);
tanButton = new QPushButton(this);
setButton(sinButton, "./img/sin.png", WIDTH - 3 * BUTTONWIDTH, HEIGHT - 7 * BUTTONHEIGHT);
setButton(cosButton, "./img/cos.png", WIDTH - 2 * BUTTONWIDTH, HEIGHT - 7 * BUTTONHEIGHT);
setButton(tanButton, "./img/tan.png", WIDTH - BUTTONWIDTH, HEIGHT - 7 * BUTTONHEIGHT);
connect(sinButton, &QPushButton::clicked, this, [=] {triFunButtonClicked("sin"); });
connect(cosButton, &QPushButton::clicked, this, [=] {triFunButtonClicked("cos"); });
connect(tanButton, &QPushButton::clicked, this, [=] {triFunButtonClicked("tan"); });
//
sqrtButton = new QPushButton(this);
squareButton = new QPushButton(this);
setButton(sqrtButton, "./img/sqrt.png", 0, HEIGHT - 6 * BUTTONHEIGHT);
setButton(squareButton, "./img/square.png", 0, HEIGHT - 7 * BUTTONHEIGHT);
connect(sqrtButton, SIGNAL(clicked()), this, SLOT(sqrtButtonClicked()));
connect(squareButton, SIGNAL(clicked()), this, SLOT(squareButtonClicked()));
//
logButton = new QPushButton(this);
expButton = new QPushButton(this);
setButton(logButton, "./img/log.png", WIDTH - 3 * BUTTONWIDTH, HEIGHT - 6 * BUTTONHEIGHT);
setButton(expButton, "./img/exp.png", WIDTH - 2 * BUTTONWIDTH, HEIGHT - 6 * BUTTONHEIGHT);
connect(logButton, &QPushButton::clicked, this, [=] {eFunButtonClicked("log"); });
connect(expButton, &QPushButton::clicked, this, [=] {eFunButtonClicked("exp"); });
//
none1 = new QPushButton(this);
none2 = new QPushButton(this);
setButton(none1, "./img/none1.png", 0, HEIGHT - 5 * BUTTONHEIGHT);
setButton(none2, "./img/none2.png", BUTTONWIDTH, HEIGHT - 5 * BUTTONHEIGHT);
//
miciButton = new QPushButton(this);
tenMiciButton = new QPushButton(this);
setButton(miciButton, "./img/mici.png", BUTTONWIDTH, HEIGHT - 7 * BUTTONHEIGHT);
setButton(tenMiciButton, "./img/tenMici.png", BUTTONWIDTH, HEIGHT - 6 * BUTTONHEIGHT);
connect(miciButton, SIGNAL(clicked()), this, SLOT(powButtonClicked()));
connect(tenMiciButton, SIGNAL(clicked()), this, SLOT(tenPowButtonClicked()));
//
factorialButton = new QPushButton(this);
setButton(factorialButton, "./img/factorial.png", 0, HEIGHT - 3 * BUTTONHEIGHT);
connect(factorialButton, &QPushButton::clicked, this, [=] {onOperatorButtonClicked('!'); });
//
positiveAndNegativeButton = new QPushButton(this);
setButton(positiveAndNegativeButton, "./img/positiveAndNegative.png", 0, HEIGHT - 2 * BUTTONHEIGHT);
connect(positiveAndNegativeButton, SIGNAL(clicked()), this, SLOT(positiveAndNegativeButtonClicked()));
// PI
piButton = new QPushButton(this);
setButton(piButton, "./img/pi.png", 0, HEIGHT - 4 * BUTTONHEIGHT);
connect(piButton, &QPushButton::clicked, this, [=] {onNumButtonClicked(3.14); });
//
clearButton = new QPushButton(this);
setButton(clearButton, "./img/clear.png", WIDTH - 3 * BUTTONWIDTH, HEIGHT - 5 * BUTTONHEIGHT);
connect(clearButton, SIGNAL(clicked()), this, SLOT(clearButtonClicked()));
//
backspaceButton = new QPushButton(this);
setButton(backspaceButton, "./img/backspace.png", WIDTH - 2 * BUTTONWIDTH, HEIGHT - 5 * BUTTONHEIGHT);
connect(backspaceButton, SIGNAL(clicked()), this, SLOT(backspaceButtonClicked()));
//
histotyButton = new QPushButton(this);
setButton(histotyButton, "./img/history.png", 0, 0, SMALLBUTTONWIDTH, SMALLBUTTONHEIGHT);
connect(histotyButton, SIGNAL(clicked()), this, SLOT(histotyButtonClicked()));
}
//
// BUTTONWIDTH(60) BUTTONHEIGHT(40)
void Calculator::setButton(QPushButton * button, const QString & filePath
, const int & width, const int & height
, const int & buttonWidth, const int & buttonHeight)
{
button->setGeometry(width, height, buttonWidth, buttonHeight);
button->setIcon(QIcon(filePath));
button->setIconSize(QSize(buttonWidth, buttonHeight));
}
//
void Calculator::initLineEdit()
{
expressionLineEdit = new QLineEdit(this);
expressionLineEdit->setGeometry(0, HEIGHT - 9 * BUTTONHEIGHT, WIDTH, BUTTONHEIGHT);
expressionLineEdit->setFont(QFont(" ", 24)); //
expressionLineEdit->setReadOnly(true); //
historyResultTextEdit = new QPlainTextEdit(this);
historyResultTextEdit->setGeometry(WIDTH, 0, ZOOMINWIDTH - WIDTH, HEIGHT);
historyResultTextEdit->setFont(QFont(" ", 24)); //
historyResultTextEdit->setReadOnly(true); //
}
// ( )
char* Calculator::getLastNum()
{
std::string s = expressionLineEdit->text().toStdString();
size_t length = strlen(s.c_str());
char res[NUMSIZE];
memset(res, '\0', NUMSIZE);
/*
* :
*
* (+,-) e
*
*/
for (int i = length - 1; i >= 0
&& (!c.isOperator(s[i])
|| (c.isOperator(s[i]) && (0 == i || 'e' == s[i - 1]))
|| ('-' == s[i] && (i == 0 || c.isOperator(s[i - 1])))); --i) {
strcpy(res, strcat(ctocstar(s[i]), res));
expressionLineEdit->backspace();
}
return res;
}
//
void Calculator::onNumButtonClicked(const qreal & num)
{
std::string tempStr = expressionLineEdit->text().toStdString();
// PI
// , PI
if (3.14 == num && "" != tempStr
&& (!c.isOperator(tempStr.back())
|| ')' == tempStr.back())) {
expressionLineEdit->setText(expressionLineEdit->text() + '*' + QString::number(num));
}
else {
expressionLineEdit->setText(expressionLineEdit->text() + QString::number(num));
}
}
void Calculator::onOperatorButtonClicked(const char & operatorName)
{
std::string tempStr = expressionLineEdit->text().toStdString();
/*
*
*
*
*
*/
if ('=' == operatorName) {
if ("" == expressionLineEdit->text()) {
QMessageBox::information(NULL, "warning!", "you can't do this!");
return;
}
if (c.isOperator(tempStr.back())) {
if (')' != tempStr.back()) {
QMessageBox::information(NULL, "warning!", "you can't put a single operator at the end!");
return;
}
}
double res = c.calculate(tempStr.c_str());
if (WRONGTAG == res) {
expressionLineEdit->clear();
}
else {
historyResultTextEdit->setPlainText(expressionLineEdit->text()
+ '='
+ QString::number(res)
+ '
'
+ historyResultTextEdit->toPlainText());
expressionLineEdit->setText(QString::number(res));
}
}
//
else if ('!' == operatorName) {
char* res = new char[NUMSIZE];
strcpy(res, getLastNum());
double d = c.stod(res);
expressionLineEdit->setText(expressionLineEdit->text() + QString::number(factorial(d)));
}
//
else if ('.' == operatorName) {
if ("" != tempStr && !c.isOperator(tempStr.back()) && '.' != tempStr.back()) {
expressionLineEdit->setText(expressionLineEdit->text() + '.');
}
}
/*
*
*
* ( ')')
*/
else if ('(' == operatorName) {
if ("" != expressionLineEdit->text() && !c.isOperator(tempStr.back())) {
expressionLineEdit->setText(expressionLineEdit->text() + '*');
}
expressionLineEdit->setText(expressionLineEdit->text() + operatorName);
}
else if ("" == expressionLineEdit->text() && '-' == operatorName) {
expressionLineEdit->setText(expressionLineEdit->text() + operatorName);
}
else if(("" != expressionLineEdit->text()
&& (!c.isOperator(tempStr.back()) && '.' != tempStr.back() || ')' == tempStr.back()))){
expressionLineEdit->setText(expressionLineEdit->text() + operatorName);
}
}
void Calculator::backspaceButtonClicked()
{
expressionLineEdit->backspace();
}
void Calculator::clearButtonClicked()
{
expressionLineEdit->clear();
}
void Calculator::triFunButtonClicked(const QString & tri)
{
char* res = new char[NUMSIZE];
strcpy(res, getLastNum());
double d = c.stod(res);
if ("sin" == tri) {
expressionLineEdit->setText(expressionLineEdit->text() + QString::number(sin(d)));
}
else if ("cos" == tri) {
expressionLineEdit->setText(expressionLineEdit->text() + QString::number(cos(d)));
}
else if ("tan" == tri) {
expressionLineEdit->setText(expressionLineEdit->text() + QString::number(tan(d)));
}
}
void Calculator::squareButtonClicked()
{
char* res = new char[NUMSIZE];
strcpy(res, getLastNum());
double d = c.stod(res);
expressionLineEdit->setText(expressionLineEdit->text() + QString::number(pow(d, 2)));
}
void Calculator::sqrtButtonClicked()
{
char* res = new char[NUMSIZE];
strcpy(res, getLastNum());
double d = c.stod(res);
expressionLineEdit->setText(expressionLineEdit->text() + QString::number(pow(d, 0.5)));
}
void Calculator::powButtonClicked()
{
expressionLineEdit->setText(expressionLineEdit->text() + "^");
}
void Calculator::tenPowButtonClicked()
{
std::string tempStr = expressionLineEdit->text().toStdString();
// PI
if ("" != tempStr && (!c.isOperator(tempStr.back())
|| ')' == tempStr.back())) {
expressionLineEdit->setText(expressionLineEdit->text() + '*');
}
expressionLineEdit->setText(expressionLineEdit->text() + "10^");
}
void Calculator::positiveAndNegativeButtonClicked()
{
// do nothing
}
void Calculator::eFunButtonClicked(const QString & e)
{
char* res = new char[NUMSIZE];
strcpy(res, getLastNum());
double d = c.stod(res);
if ("exp" == e) {
expressionLineEdit->setText(expressionLineEdit->text() + QString::number(exp(d)));
}
else if ("log" == e) {
if (d <= 0) {
QMessageBox::information(NULL, "warning!", "you can't use this number as the base");
expressionLineEdit->clear();
}
else {
expressionLineEdit->setText(expressionLineEdit->text() + QString::number(log(d)));
}
}
}
void Calculator::histotyButtonClicked()
{
if (false == zoomin) {
setMinimumSize(ZOOMINWIDTH, HEIGHT);
setMaximumSize(ZOOMINWIDTH, HEIGHT);
zoomin = true;
}
else if (true == zoomin) {
setMinimumSize(WIDTH, HEIGHT);
setMaximumSize(WIDTH, HEIGHT);
zoomin = false;
}
}
calculation.h
#pragma once
#include "vector.h"
#include "stack.h"
#include
const int NUMSIZE = 20; //
const int WRONGTAG = -INT_MAX; //
class calculation {
public:
double stod(char* s);
bool isOperator(const char c);
double calculate(const char* expressions);
};
char* ctocstar(char c);
calculation.cpp
#pragma warning(disable:4996)
#include "calculation.h"
const char* operators = "+-*/%()^";
//
int icp(const char c)
{
switch (c)
{
case '(':return 6;
case '*':
case '/':
case '^':
case '%':return 4;
case '+':
case '-':return 2;
case ')':return 1;
default:break;
}
return 0;
}
//
int isp(const char c)
{
switch (c)
{
case '(':return 1;
case '*':
case '/':
case '^':
case '%':return 5;
case '+':
case '-':return 3;
case ')':return 6;
default:break;
}
return 0;
}
//
double calculation::stod(char * s)
{
double res = 0;
bool isNegative = s[0] == '-' ? true : false; //
int i = 0;
int size = 0; // ( e )
int ePos = -1; // e , -1
int pointPos = -1; // , -1
for (i = isNegative; s[i] != '\0'; ++i) {
if (s[i] == '.') {
pointPos = i;
size++;
}
else if (s[i] == 'e') {
ePos = i;
break;
}
else {
size++;
}
}
//
for (i = isNegative; i < size + isNegative; ++i) {
if (i == pointPos) {
continue;
}
res = res * 10 + (s[i] - '0');
}
if (-1 != pointPos) {
while (size != pointPos + 1) {
res = res / 10;
size--;
}
}
//
if (-1 != ePos) {
int exponential = 0; //
bool isNegativeExp = s[ePos + 1] == '-' ? true : false; //
for (i = ePos + 2; s[i] != '\0'; ++i) {
exponential = exponential * 10 + (s[i] - '0');
}
if (isNegativeExp) {
while (exponential--) {
res /= 10;
}
}
else {
while (exponential--) {
res *= 10;
}
}
}
return isNegative ? -res : res;
}
bool calculation::isOperator(const char c)
{
for (int i = 0; operators[i] != '\0'; ++i) {
if (c == operators[i]) {
return true;
}
}
return false;
}
char* ctocstar(const char c) {
char *ch = new char[2];
ch[0] = c;
ch[1] = '\0';
return ch;
}
double calculation::calculate(const char * expressions)
{
if ("" == expressions) {
return WRONGTAG;
}
Stack numStack; //
Stack symStack; //
//
char num[NUMSIZE]; //
sprintf_s(num, NUMSIZE, "%c", '\0');
char temp = NULL;
Vector sufExpressions;
int i = NULL;
for (i = 0; expressions[i] != '\0'; ++i) {
temp = expressions[i];
// num
// e
if (!isOperator(temp) || (isOperator(temp) && expressions[i - 1] == 'e')) {
sprintf_s(num, NUMSIZE, "%s%c", num, temp);
}
//
else {
char *tempch = new char[NUMSIZE];
strcpy(tempch, num);
if (num[0] != '\0') {
sufExpressions.push_back(tempch); //
}
sprintf_s(num, NUMSIZE, "%c", '\0');
/*
*
*
* ,
* ,
*/
if (')' == temp) {
// ,
while (!symStack.empty() && symStack.top() != '(') {
sufExpressions.push_back(ctocstar(symStack.top()));
symStack.pop();
}
//
if (symStack.empty()) {
QMessageBox::information(NULL, "warning!", "lack of leftparentheses!");
return WRONGTAG;
}
else {
//
symStack.pop();
}
}
else {
while (!symStack.empty() && (isp(symStack.top()) > icp(temp))) {
sufExpressions.push_back(ctocstar(symStack.top()));
symStack.pop();
}
symStack.push(temp);
}
}
}
//
if (num[0] != '\0') {
sufExpressions.push_back(num);
}
//
while (!symStack.empty()) {
sufExpressions.push_back(ctocstar(symStack.top()));
symStack.pop();
}
double tempNum1 = NULL, tempNum2 = NULL;
//
for (i = 0; i < sufExpressions.size(); ++i) {
if (0 == strcmp(sufExpressions[i], "+")) {
tempNum1 = numStack.top();
numStack.pop();
tempNum2 = numStack.top();
numStack.pop();
numStack.push(tempNum1 + tempNum2);
}
else if (0 == strcmp(sufExpressions[i], "-")) {
tempNum1 = numStack.top();
numStack.pop();
// ( )
if (numStack.empty() || (i < sufExpressions.size() - 1 && isOperator(sufExpressions[i + 1][0]))) {
tempNum2 = 0;
}
else {
tempNum2 = numStack.top();
numStack.pop();
}
numStack.push(tempNum2 - tempNum1);
}
else if (0 == strcmp(sufExpressions[i], "*")) {
tempNum1 = numStack.top();
numStack.pop();
tempNum2 = numStack.top();
numStack.pop();
numStack.push(tempNum1 * tempNum2);
}
else if (0 == strcmp(sufExpressions[i], "/")) {
tempNum1 = numStack.top();
numStack.pop();
tempNum2 = numStack.top();
numStack.pop();
// 0
if (tempNum1 == 0) {
QMessageBox::information(NULL, "warning!", "you can't divide zero!");
return WRONGTAG;
}
else {
numStack.push(tempNum2 / tempNum1);
}
}
else if (0 == strcmp(sufExpressions[i], "%")) {
tempNum1 = numStack.top();
numStack.pop();
tempNum2 = numStack.top();
numStack.pop();
// 0
if (tempNum2 < 0) {
numStack.push(tempNum1 + (tempNum2 - (int)(tempNum2 / tempNum1) * tempNum1));
}
else {
numStack.push(tempNum2 - (int)(tempNum2 / tempNum1) * tempNum1);
}
}
else if (0 == strcmp(sufExpressions[i], "^")) {
tempNum1 = numStack.top();
numStack.pop();
tempNum2 = numStack.top();
numStack.pop();
numStack.push(pow(tempNum2, tempNum1));
}
else if (0 == strcmp(sufExpressions[i], "(")) {
QMessageBox::information(NULL, "warning!", "lack of rightparenteses!");
return WRONGTAG;
}
else {
numStack.push(stod(sufExpressions[i]));
}
}
// 0
if (numStack.empty()) {
return 0;
}
return numStack.top();
}
リンク:https://share.weiyun.com/5A45cgb
画像の素材はリンクの中にあって、マイクロソフトのコンピュータのスクリーンショットです