history.h
#ifndef HISTORY_H
#define HISTORY_H
#include <QWidget>
namespace Ui {
class history;
}
class history : public QWidget
{
Q_OBJECT
public:
explicit history(QWidget *parent = 0);
~history();
public:
Ui::history *ui;
};
#endif // HISTORY_H
widget.h
#ifndef WIDGET_H
#define WIDGET_H
#include <QWidget>
#include <QString>
#include <QStack>
#include <QDialog>
#include "history.h"
#include <QIcon>
namespace Ui {
class Widget;
}
class Widget : public QWidget
{
Q_OBJECT
public:
explicit Widget(QWidget *parent = nullptr);
~Widget();
void paintEvent(QPaintEvent *event);
private slots:
void on_Button_1_clicked();
void on_Button_2_clicked();
void on_Button_3_clicked();
void on_Button_4_clicked();
void on_Button_5_clicked();
void on_Button_6_clicked();
void on_Button_8_clicked();
void on_Button_7_clicked();
void on_Button_9_clicked();
void on_Button_add_clicked();
void on_Button_0_clicked();
void on_Button_point_clicked();
void on_Button_subtract_clicked();
void on_Button_multiply_clicked();
void on_Button_divide_clicked();
void on_Button_clear_clicked();
void on_Button_back_clicked();
void on_Button_equal_clicked();
void on_Button_left_clicked();
void on_Button_right_clicked();
void on_Button_history_clicked();
private:
Ui::Widget *ui;
//储存两个表达式
QString expression;
QString Expression;
//建立“历史记录”对话框的对象
history history_dia;
//判断“历史记录”对话框是否打开
bool isOpen;
private:
//下面的函数可以将中缀表达式转换为后缀表达式
//运算符s位于栈外的优先级
int icp(QString s);
//运算符s位于栈内的优先级
int isp(QString s);
//将分割后的字符串作为参数,返回后缀表达式。
QStringList Transform(QStringList ex);
//实现后缀表达式的计算
private:
QStack<double> s;
//开始计算
double Run(QStringList exx);
//计算当前运算符ch
void calculate(char ch);
//从栈中取出两个操作数left和rigth
bool GetOperand(double& left,double& right);
};
#endif // WIDGET_H
main.cpp
#include "widget.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
Widget w;
w.show();
return a.exec();
}
history.cpp
#include "history.h"
#include "ui_history.h"
history::history(QWidget *parent) :
QWidget(parent),
ui(new Ui::history)
{
ui->setupUi(this);
//更改窗口属性
setWindowTitle("历史记录");
}
history::~history()
{
delete ui;
}
widget.h
#include "widget.h"
#include "ui_widget.h"
#include <QDebug>
#include "history.h"
#include "ui_history.h"
#include <QSize>
#include<QPainter>
//构造函数
Widget::Widget(QWidget *parent) :
QWidget(parent),
ui(new Ui::Widget)
{
ui->setupUi(this);
QSize qsize(51,51);
ui->Button_history->setIconSize(qsize);
this->isOpen=false;//开始时,历史记录对话框未打开
//初始化主窗体
setWindowTitle(QString("简易计算器"));
}
void Widget::paintEvent(QPaintEvent *event)
{
Q_UNUSED(event);
QPainter p(this);
p.setPen(Qt::NoPen);
p.setBrush(Qt::lightGray);
p.drawRect(rect());
}
//析构函数
Widget::~Widget()
{
delete ui;
}
int Widget::icp(QString s){
if(s=="#")
return 0;
else if(s=="(")
return 9;
else if(s=="*"||s=="/"||s=="%")
return 5;
else if(s=="+"||s=="-")
return 3;
else if(s==")")
return 1;
else {
ui->Screen->setText("错误!");
return -1;
}
}
//运算符在栈内优先级
int Widget::isp(QString s){
if(s=="#")
return 0;
else if(s=="(")
return 1;
else if(s=="*"||s=="/"||s=="%")
return 6;
else if(s=="+"||s=="-")
return 4;
else if(s==")")
return 9;
else {
ui->Screen->setText("错误!");
return -1;
}
}
//中缀转换成后缀表达式
QStringList Widget::Transform(QStringList ex){
QStack<QString> stack;
stack.push("#");
QStringList anssss;
for(int i=0;!stack.isEmpty();){
//如果ex[i]是操作数,则存入inssss中,直到遇到操作符为止。
if(ex[i]!="+"&&ex[i]!="-"&&ex[i]!="*"&&ex[i]!="/"&&ex[i]!="%"
&&ex[i]!="("&&ex[i]!=")"&&ex[i]!="#"){
anssss.insert(i,ex[i]);
i++;
}
//遇到了操作符时:
else {
//接下来处理操作符ex[i]
//若栈外操作符ex[i]优先级大于栈内操作符stack.top()优先级,则ex[i]进栈
if(icp(ex[i])>isp(stack.top())){
stack.push(ex[i]);
i++;
}
//若栈外操作符优先级小于栈内操作符优先级,则将栈内操作符输出到后缀表达式,并出栈。
else if(icp(ex[i])<isp(stack.top()))
{
QString x=stack.top();
anssss.insert(i,x);
stack.pop();
}
//若栈外栈内优先级相同,退栈不输出。同时,如果栈内是“(“,则读取下一字符
else if(icp(ex[i])==isp(stack.top())){
QString pop=stack.top();
stack.pop();
if(pop=="(")
i++;
}
}
}
return anssss;
}
//取出两个操作数
bool Widget::GetOperand(double& left,double& right){
right=s.top();
s.pop();
left=s.top();
s.pop();
}
//开始计算
double Widget::Run(QStringList exx){
int i=0;double l,r;
while(i<exx.length()){
if(exx[i]!=""&&exx[i]!="+"&&exx[i]!="-"&&exx[i]!="*"&&exx[i]!="/"){
//操作数进栈
s.push(exx[i].toDouble());
i++;
}
else if(exx[i]!=""){
if(exx[i]=="+"){
this->GetOperand(l,r);
s.push(l+r);
i++;
}
else if(exx[i]=="-"){
this->GetOperand(l,r);
s.push(l-r);
i++;
}
else if(exx[i]=="*"){
this->GetOperand(l,r);
s.push(l*r);
i++;
}
else if(exx[i]=="/"){
this->GetOperand(l,r);
s.push(l/r);
i++;
}
}
else{
i++;
}
}
double ans=s.top();
s.pop();
//将“历史”对话框中的label文本改变。
history_dia.ui->label->setText("历史记录:");
ui->Screen->setText(expression+"="+QString::number(ans));
return ans;
}
//槽函数 当数字式0到9时,如果上个输入是右括号则不输入
void Widget::on_Button_1_clicked()
{ int i=expression.length()-1;
if(expression .length()==0){
Expression += "1";
expression += "1";
ui->Screen->setText(expression);
}
else if(expression.at(i) == ")")
{
ui->Screen->setText(expression);
}
else{
Expression += "1";
expression += "1";
ui->Screen->setText(expression);}
}
void Widget::on_Button_2_clicked()
{
int i=expression.length()-1;
if(expression .length()==0){
Expression += "2";
expression += "2";
ui->Screen->setText(expression);
}
else if(expression.at(i) == ")")
{
ui->Screen->setText(expression);
}
else{
Expression += "2";
expression += "2";
ui->Screen->setText(expression);}
}
void Widget::on_Button_3_clicked(){
int i=expression.length()-1;
if(expression .length()==0){
Expression += "3";
expression += "3";
ui->Screen->setText(expression);
}
else if(expression.at(i) == ")")
{
ui->Screen->setText(expression);
}
else{
Expression += "3";
expression += "3";
ui->Screen->setText(expression);}
}
void Widget::on_Button_4_clicked()
{
int i=expression.length()-1;
if(expression .length()==0){
Expression += "4";
expression += "4";
ui->Screen->setText(expression);
}
else if(expression.at(i) == ")")
{
ui->Screen->setText(expression);
}
else{
Expression += "4";
expression += "4";
ui->Screen->setText(expression);}
}
void Widget::on_Button_5_clicked()
{
int i=expression.length()-1;
if(expression .length()==0){
Expression += "5";
expression += "5";
ui->Screen->setText(expression);
}
else if(expression.at(i) == ")")
{
ui->Screen->setText(expression);
}
else{
Expression += "5";
expression += "5";
ui->Screen->setText(expression);}
}
void Widget::on_Button_6_clicked()
{
int i=expression.length()-1;
if(expression .length()==0){
Expression += "6";
expression += "6";
ui->Screen->setText(expression);
}
else if(expression.at(i) == ")")
{
ui->Screen->setText(expression);
}
else{
Expression += "6";
expression += "6";
ui->Screen->setText(expression);}
}
void Widget::on_Button_8_clicked(){
int i=expression.length()-1;
if(expression .length()==0){
Expression += "8";
expression += "8";
ui->Screen->setText(expression);
}
else if(expression.at(i) == ")")
{
ui->Screen->setText(expression);
}
else{
Expression += "8";
expression += "8";
ui->Screen->setText(expression);}
}
void Widget::on_Button_7_clicked()
{ int i=expression.length()-1;
if(expression .length()==0){
Expression += "7";
expression += "7";
ui->Screen->setText(expression);
}
else if(expression.at(i) == ")")
{
ui->Screen->setText(expression);
}
else{
Expression += "7";
expression += "7";
ui->Screen->setText(expression);}
}
void Widget::on_Button_9_clicked()
{
int i=expression.length()-1;
if(expression .length()==0){
Expression += "9";
expression += "9";
ui->Screen->setText(expression);
}
else if(expression.at(i) == ")")
{
ui->Screen->setText(expression);
}
else{
Expression += "9";
expression += "9";
ui->Screen->setText(expression);}
}
void Widget::on_Button_add_clicked()
{int i =expression .length() - 1;
if(expression .length()==0|| expression.at(i) == "(" ){//如果前面无输入或者时左括号则补0
Expression += "0~+~";
expression += "+";
ui->Screen->setText(expression);}
//连续输入运算符,则不输入
else if (expression.at(i) == "+"|| expression.at(i) == "-" || expression.at(i) == "*" || expression.at(i) == "/")
{
ui->Screen->setText(expression);
}
else{
Expression += "~+~";
expression += "+";
ui->Screen->setText(expression);
}
}
void Widget::on_Button_0_clicked()
{
int i=expression.length()-1;
if(expression .length()==0){
Expression += "0";
expression += "0";
ui->Screen->setText(expression);
}
else if(expression.at(i) == ")")
{
ui->Screen->setText(expression);
}
else{
Expression += "0";
expression += "0";
ui->Screen->setText(expression);}
}
//如果当前按钮是 ‘.’如果前面有括号操作符小数点什么也不做
void Widget::on_Button_point_clicked()
{//如果小数点前无数字,则补0
int i =expression .length() - 1;
if(expression.length()==0||(expression.at(i) == "+"|| expression.at(i) == "-" || expression.at(i) == "*" || expression.at(i) == "/"|| expression.at(i) == "(" )){
Expression += "0.";
expression += ".";
ui->Screen->setText(expression);
}
//如果是右括号则不输入
else if(expression.at(i) == ")"||expression.at(i) == ".")
{
ui->Screen->setText(expression);
}
//如果数字中有了小数点,则不输入
else {
int falg1=0;//设置标志
int j;
//判断字符中是否有".",j为数字首字符串位置
for( j=expression .length() - 1;j>0;j--){
if(expression.at(j) == "+"|| expression.at(j) == "-" || expression.at(j) == "*" || expression.at(j) == "/"|| expression.at(j) == "(" || expression.at(j) == ")")
break;
}
//判断数字字符串是否已经有"."
for(int t=expression .length() - 1;t>j;t--)
if(expression.at(t) == "."){
falg1=1;
}
//如果有则什么也不输出
if(falg1==1){
ui->Screen->setText(expression);
}
//否则输出点
else{
Expression += ".";
expression += ".";
ui->Screen->setText(expression);
}
}
}
void Widget::on_Button_subtract_clicked()
{int i =expression .length() - 1;
if(expression.length()==0|| expression.at(i) == "(" ){
Expression += "0~-~";
expression += "-";
ui->Screen->setText(expression);
}
else if (expression.at(i) == "+"|| expression.at(i) == "-" || expression.at(i) == "*" || expression.at(i) == "/")
{
ui->Screen->setText(expression);
}
else{
Expression += "~-~";
expression += "-";
ui->Screen->setText(expression);
}
}
void Widget::on_Button_multiply_clicked()
{
int i =expression .length() - 1;
if(expression.length()==0|| expression.at(i) == "(" ){
Expression += "1~*~";
expression += "*";
ui->Screen->setText(expression);
}
else if (expression.at(i) == "+"|| expression.at(i) == "-" || expression.at(i) == "*" || expression.at(i) == "/")
{
ui->Screen->setText(expression);
}
else{
Expression += "~*~";
expression += "*";
ui->Screen->setText(expression);
}
}
void Widget::on_Button_divide_clicked()
{
int i =expression .length() - 1;
if(expression.length()==0||expression.at(i) == "("){//如果前面无输入或者时左括号
ui->Screen->setText(expression);
}
else if (expression.at(i) == "+"|| expression.at(i) == "-" || expression.at(i) == "*" || expression.at(i) == "/")
{
ui->Screen->setText(expression);
}
else{
Expression += "~/~";
expression += "/";
ui->Screen->setText(expression);
}
}
void Widget::on_Button_clear_clicked()
{
Expression.clear();
expression.clear();
ui->Screen->clear();
//ui->Label->clear();
}
void Widget::on_Button_back_clicked()
{
//只有lineedit中有输入才可以删除
if(expression.length()!=0){
if(Expression[Expression.length()-1]=="~")
Expression.chop(3);
else
Expression.chop(1);
expression.chop(1);
ui->Screen->setText(expression);
}
}
//左括号限制输入
void Widget::on_Button_left_clicked()
{
int i;
i=expression .length();
if(expression.length()==0){
expression += "(";
Expression += "~(~";
ui->Screen->setText(expression);
}
//for( i=expression .length() - 1;i>=0;i--){
else if(expression.at(i-1) == "+"|| expression.at(i-1) == "-" || expression.at(i-1) == "*" || expression.at(i-1) == "/"||expression.at(i-1) == "(")
{
expression += "(";
Expression += "~(~";
ui->Screen->setText(expression);
}
else{
ui->Screen->setText(expression);
}
}
//右括号限制输入
void Widget::on_Button_right_clicked()
{
// int flag1=0;
int i=expression.length();
int count1=0;
int count2=0;
for(int j=expression .length() - 1;j>=0;j--){
if(expression.at(j)=="("){
count1++;
}
else if(expression.at(j)==")"){
count2++;
}
}
if(expression.length()==0){
ui->Screen->setText(expression);
}
else if(expression.at(i-1) == "+"|| expression.at(i-1) == "-" || expression.at(i-1) == "*" || expression.at(i-1) == "/"||expression.at(i-1)==")"||expression.at(i-1)=="("){
ui->Screen->setText(expression);
}
else if(count1>count2){
expression += ")";
Expression += "~)~";
ui->Screen->setText(expression);
}
}
//等号按钮点击事件
void Widget::on_Button_equal_clicked()
{ //空字符输入 缺少操作数则不输入,也不输出
int i=expression.length()-1;
if (expression.length() == 0||expression.at(i) == "+"|| expression.at(i) == "-" || expression.at(i) == "*" || expression.at(i) == "/")
{
return;
}
else if(expression.length() != 0){
//补全右括号
int count1=0;
int count2=0;
for(int j=expression .length() - 1;j>=0;j--){
if(expression.at(j)=="("){
count1++;
}
else if(expression.at(j)==")"){
count2++;
}
}
if(count1>count2){
int t=count1-count2;
while(t>0){
expression += ")";
Expression += "~)~";
t--;
}
}
}
//将Expression分割,存入字符串数组ex中。ex最后一位为"#"
QStringList ex=Expression.split("~");
ex.insert(ex.length(),"#");
//计算
double Ans=this->Run(this->Transform(ex));
//将结果添加到“历史”对话框的最后并换行
history_dia.ui->textBrowser->setText
(history_dia.ui->textBrowser->document()->toPlainText()+expression+"="+QString::number(Ans)+"\n");
//将两个E/expression归零
expression.clear();
Expression.clear();
}
//展开历史对话框
void Widget::on_Button_history_clicked()
{
if(isOpen==false){
history_dia.show();
isOpen=true;
}
else if(isOpen==true){
history_dia.close();
isOpen=false;
}
}