QT的计算器编写还是有很多资料的,这里给的程序包含了两种计算器。
一种是功能简单的计算器,只能实现整数 +-*/,适合刚学习的小伙伴。
另一种是包含小数,括号的计算器,需要用到中缀的转换。
calculator.h
#ifndef CALCULATOR_H
#define CALCULATOR_H
#include <QDialog>
#include<qlineedit.h>
#include<qpushbutton.h>
#include<QHBoxLayout>
#include<QVBoxLayout>
class Calculator : public QDialog
{
Q_OBJECT
public:
Calculator(QWidget *parent = 0);
~Calculator();
int num1, num2;
double result;
QString str;
char opera;
QLineEdit *lineEdit;
QPushButton *button_0;
QPushButton *button_1;
QPushButton *button_2;
QPushButton *button_3;
QPushButton *button_4;
QPushButton *button_5;
QPushButton *button_6;
QPushButton *button_7;
QPushButton *button_8;
QPushButton *button_9;
QPushButton *button_add;
QPushButton *button_sub;
QPushButton *button_mul;
QPushButton *button_div;
QPushButton *button_dot;
QPushButton *button_bra;
QPushButton *button_ket;
QPushButton *button_eql;
//QPushButton *button_ce;
private slots:
void button_0_clicked();
void button_1_clicked();
void button_2_clicked();
void button_3_clicked();
void button_4_clicked();
void button_5_clicked();
void button_6_clicked();
void button_7_clicked();
void button_8_clicked();
void button_9_clicked();
void button_add_clicked();
void button_sub_clicked();
void button_mul_clicked();
void button_div_clicked();
void button_eql_clicked();
void button_bra_clicked();
void button_ket_clicked();
void button_dot_clicked();
};
#endif // CALCULATOR_H
calculator.cpp
#include "calculator.h"
#include<expression.h>
#include<iostream>
#include<QString>
Calculator::Calculator(QWidget *parent)
: QDialog(parent)
{
num1 = 0;
num2 = 0;
result = 0;
str = "";
//初始化控件
lineEdit = new QLineEdit("0");
button_0 = new QPushButton("0");
button_1 = new QPushButton("1");
button_2 = new QPushButton("2");
button_3 = new QPushButton("3");
button_4 = new QPushButton("4");
button_5 = new QPushButton("5");
button_6 = new QPushButton("6");
button_7 = new QPushButton("7");
button_8 = new QPushButton("8");
button_9 = new QPushButton("9");
button_add = new QPushButton("+");
button_sub = new QPushButton("-");
button_mul = new QPushButton("*");
button_div = new QPushButton("/");
button_eql = new QPushButton("=");
button_bra = new QPushButton("(");
button_ket = new QPushButton(")");
button_dot = new QPushButton(".");
button_eql->setStyleSheet("background-color: rgb(255, 80,20);");//132, 139
//布局控件
/*先将水平控件布局好,再将水平布局嵌入垂直布局;
//每个水平布局是垂直布局的控件。
QHBoxLayout *Hl1 = new QHBoxLayout;
QHBoxLayout *Hl2 = new QHBoxLayout;
QHBoxLayout *Hl3 = new QHBoxLayout;
QHBoxLayout *Hl4 = new QHBoxLayout;
QHBoxLayout *Hl5 = new QHBoxLayout;
Hl1->addWidget(lineEdit);
Hl1->addWidget(button_ce);
Hl2->addWidget(button_1);
Hl2->addWidget(button_2);
Hl2->addWidget(button_3);
Hl2->addWidget(button_add);
Hl3->addWidget(button_4);
Hl3->addWidget(button_5);
Hl3->addWidget(button_6);
Hl3->addWidget(button_sub);
Hl4->addWidget(button_7);
Hl4->addWidget(button_8);
Hl4->addWidget(button_9);
Hl4->addWidget(button_mul);
Hl5->addWidget(button__);
Hl5->addWidget(button_0);
Hl5->addWidget(button_eql);
Hl5->addWidget(button_div);//addWidget,添加小部件
QVBoxLayout *V1 = new QVBoxLayout;
V1->addLayout(Hl1);
V1->addLayout(Hl2);
V1->addLayout(Hl3);
V1->addLayout(Hl4);
V1->addLayout(Hl5); //addLayout,添加布局
setLayout(V1);
*/
//QGridLayout格栅布局
QGridLayout *H = new QGridLayout();
H->addWidget(lineEdit, 0, 0, 1, 2);
H->addWidget(button_add, 0, 3, 1, 1);
H->addWidget(button_0, 0, 2, 1, 1);
H->addWidget(button_1, 1, 0, 1, 1);
H->addWidget(button_2, 1, 1, 1, 1);
H->addWidget(button_3, 1, 2, 1, 1);
H->addWidget(button_sub, 1, 3, 1, 1);
H->addWidget(button_4, 2, 0, 1, 1);
H->addWidget(button_5, 2, 1, 1, 1);
H->addWidget(button_6, 2, 2, 1, 1);
H->addWidget(button_mul, 2, 3, 1, 1);
H->addWidget(button_7, 3, 0, 1, 1);
H->addWidget(button_8, 3, 1, 1, 1);
H->addWidget(button_9, 3, 2, 1, 1);
H->addWidget(button_div, 3, 3, 1, 1);
H->addWidget(button_bra, 4, 0, 1, 1);
H->addWidget(button_ket, 4, 1, 1, 1);
H->addWidget(button_dot, 4, 2, 1, 1);
H->addWidget(button_eql, 4, 3, 1, 1);
H->setHorizontalSpacing(10);
H->setVerticalSpacing(10);
H->setContentsMargins(10, 10, 10, 10);
setLayout(H);
//信号与槽函数连接
connect(button_0, SIGNAL(clicked()), this, SLOT(button_0_clicked()));
connect(button_1, SIGNAL(clicked()), this, SLOT(button_1_clicked()));
connect(button_2, SIGNAL(clicked()), this, SLOT(button_2_clicked()));
connect(button_3, SIGNAL(clicked()), this, SLOT(button_3_clicked()));
connect(button_4, SIGNAL(clicked()), this, SLOT(button_4_clicked()));
connect(button_5, SIGNAL(clicked()), this, SLOT(button_5_clicked()));
connect(button_6, SIGNAL(clicked()), this, SLOT(button_6_clicked()));
connect(button_7, SIGNAL(clicked()), this, SLOT(button_7_clicked()));
connect(button_8, SIGNAL(clicked()), this, SLOT(button_8_clicked()));
connect(button_9, SIGNAL(clicked()), this, SLOT(button_9_clicked()));
connect(button_add, SIGNAL(clicked()), this, SLOT(button_add_clicked()));
connect(button_sub, SIGNAL(clicked()), this, SLOT(button_sub_clicked()));
connect(button_mul, SIGNAL(clicked()), this, SLOT(button_mul_clicked()));
connect(button_div, SIGNAL(clicked()), this, SLOT(button_div_clicked()));
connect(button_eql, SIGNAL(clicked()), this, SLOT(button_eql_clicked()));
connect(button_bra, SIGNAL(clicked()), this, SLOT(button_bra_clicked()));
connect(button_ket, SIGNAL(clicked()), this, SLOT(button_ket_clicked()));
connect(button_dot, SIGNAL(clicked()), this, SLOT(button_dot_clicked()));
}
Calculator::~Calculator()
{
}
void Calculator::button_0_clicked()
{
str += "0";
lineEdit->setText(str);
}
void Calculator::button_1_clicked()
{
str += "1";
lineEdit->setText(str);
}
void Calculator::button_2_clicked()
{
str += "2";
lineEdit->setText(str);
}
void Calculator::button_3_clicked()
{
str += "3";
lineEdit->setText(str);
}
void Calculator::button_4_clicked()
{
str += "4";
lineEdit->setText(str);
}
void Calculator::button_5_clicked()
{
str += "5";
lineEdit->setText(str);
}
void Calculator::button_6_clicked()
{
str += "6";
lineEdit->setText(str);
}
void Calculator::button_7_clicked()
{
str += "7";
lineEdit->setText(str);
}
void Calculator::button_8_clicked()
{
str += "8";
lineEdit->setText(str);
}
void Calculator::button_9_clicked()
{
str += "9";
lineEdit->setText(str);
}
void Calculator::button_dot_clicked()
{
str += ".";
lineEdit->setText(str);
}
void Calculator::button_add_clicked()
{
str += "+";
lineEdit->setText(str);
opera = '+';
}
void Calculator::button_sub_clicked()
{
str += "-";
lineEdit->setText(str);
opera = '-';
}
void Calculator::button_mul_clicked()
{
str += "*";
lineEdit->setText(str);
opera = '*';
}
void Calculator::button_div_clicked()
{
str += "/";
lineEdit->setText(str);
opera = '/';
}
void Calculator::button_bra_clicked()
{
str += "(";
lineEdit->setText(str);
}
void Calculator::button_ket_clicked()
{
str += ")";
lineEdit->setText(str);
}
void Calculator::button_eql_clicked()
{
//简单计算器
//str += "=";
/*int pos = 0;
//int postail= str.indexOf('=');
QString str1, str2;
switch (opera)
{
case '+':pos = str.indexOf('+'); break;
case '-':pos = str.indexOf('-'); break;
case '*':pos = str.indexOf('*'); break;
case '/':pos = str.indexOf('/'); break;
}
//pos = str.lastIndexOf('+');
str1 = str.mid(0, pos);
str2 = str.mid(pos + 1);
bool ok;
num1 = str1.toInt(&ok);
num2 = str2.toInt(&ok);
switch (opera) {
case '+':result = num1 + num2; break;
case '-':result = num1 - num2; break;
case '*':result = num1 * num2; break;
case '/':result = (double) num1 / num2; break;
}
str += "=";
str += QString::number(result);
lineEdit->setText(str);
num1 = 0;
num2 = 0;
str = "";
*/
vector<string> tmp;
string sstr = str.toStdString();//QString to string
tmp = preExpression(sstr);
int len1 = tmp.size();
stack<string> st;
for (int i = len1 - 1; i >= 0; i--)
{
st.push(tmp[i]);
}
result = calculatenew(st);
str += "=";
str += QString::number(result);
lineEdit->setText(str);
str = "";
}
expression.cpp 中缀转前缀
#include<expression.h>
int getPriority(char ch)//操作符优先级
{
int prio = 0;
if (ch == '*' || ch == '/')
prio = 2;
else if (ch == '+' || ch == '-')
prio = 1;
else if (ch == ')')
prio = 0;
return prio;
}
//判断字符是否是数字
// if(isdigit(str[j]))
//isalnum() 用来判断一个字符是否为英文字母或数字,相当于 isalpha(c) || isdigit(c)
//isalpha() 用来判断一个字符是否是英文字母,相当于 isupper(c)||islower(c)大小写
int getNum(string str)
{
int len = str.size();
int mark = 0;
for (int i = len - 1; i >= 0; i--)
{
if (isdigit(str[i])) continue;
if (str[i] == '.') continue;
if (!isdigit(str[i])) { mark = i + 1; break; }
}
return mark;
}
string chtos(char c)
{
char tmp[1];
tmp[0] = c;
string result(tmp, 1);
return result;
}
string dtos(double d) {//double to string
ostringstream os;
if (os << d) return os.str();
else return "invalid conversion";
}
vector<string> preExpression(string str)
{
vector<string> number;
stack<char> notation;
int len = str.size();
int pos;
for (int i = len - 1; i >= 0; i--)
{
if (isdigit(str[i]))
{
pos = getNum(str.substr(0, i + 1));
number.push_back(str.substr(pos, i - pos + 1));
i = pos;
}
else {
if (notation.empty() || str[i] == ')') notation.push(str[i]);
else if (str[i] == '(')
{
while (notation.top() != ')')
{
number.push_back(chtos(notation.top()));
notation.pop();
}
notation.pop();
}
else if (!notation.empty() && getPriority(str[i]) >= getPriority(notation.top()))
{
notation.push(str[i]);
}
else if (!notation.empty() && getPriority(str[i])<getPriority(notation.top()))
{
number.push_back(chtos(notation.top()));
notation.pop();
notation.push(str[i]);
}
}
}
while (!notation.empty())
{
number.push_back(chtos(notation.top()));
notation.pop();
}
return number;
}
double calculatenew(stack<string> st)
{
stack <string> operation;
double lope;
double rope;
double result;
while (!st.empty())
{
string tmp = st.top();
if (isdigit(*tmp.begin()))
{
operation.push(st.top());
st.pop();
}
else
{
string ch = st.top();
if (ch == "+")
{
lope = atof(operation.top().c_str());
operation.pop();
rope = atof(operation.top().c_str());
operation.pop();
result = lope + rope;
operation.push(dtos(result));
}
if (ch == "-")
{
lope = atof(operation.top().c_str());
operation.pop();
rope = atof(operation.top().c_str());
result = lope - rope;
operation.pop();
operation.push(dtos(result));
}
if (ch == "*")
{
lope = atof(operation.top().c_str());
operation.pop();
rope = atof(operation.top().c_str());
result = lope*rope;
operation.pop();
operation.push(dtos(result));
}
if (ch == "/")
{
lope = atof(operation.top().c_str());
operation.pop();
rope = atof(operation.top().c_str());
result = lope / rope;
operation.pop();
operation.push(dtos(result));
}
st.pop();
}
}
return result;
}