QT,计算器实现(四则运算,括号,小数,负数)---(一)

来源:互联网 发布:淘宝钱扣了没付款成功 编辑:程序博客网 时间:2024/05/14 18:27

初学Qt,制作一个简单计算器。
先上效果图:
这里写图片描述
上面显示框,用于显示输入:
如:1*2-(3-8)+2*6
这里写图片描述
按下等于键,下面显示框显示输出结果:
这里写图片描述
1,计算器界面设计
因为本人初学,就直接在ui界面画出所需界面了,如下:
这里写图片描述
在界面画好之后,记得要布局,让其界面一直处于居中状态,另外可以右键,选择修改每个控件名字,便于对各个控件编程。
2,总体设计思路。
由界面设计。我们可以看出,有两个显示框,当我们输入表达式时,要实时显示到界面上,那我们可以将上面的框用于显示输入表达式,下面的框用于显示输入的数据及最后的运算结果。
我们定义一个结构体:
struct put_ctrl_t{
QString old_put; //用于表达式的存储
QString new_put; //用于输入的数据存储
int brackets_cnt; //左括号输入个数
int update_flag; //当new_put为“0”时,重新输入0表示更新置1
};
计算器是模仿win10的自带的标准计算器,显示方式和其相似。
当我们输入1+2=时,
(1)—>input 1
old_put = “0”;//初始值
new_put = “1”;

(2)—->input +
old_put = “1+”;//显示到上框
new_put = “0”;//初始化

(3)—->input 2
old_put = “1+”;//显示到上框
new_put = “2”;

(4)—->input =
old_put = “1+2”;//不显示,计算结果显示到下框,上框清空
new_put = “0”;
old_put = “0”;//初始化

3,计算器按键输入信号绑定connect。

/*所有按键,信号连接*/    connect(ui>button_0,SIGNAL(clicked()),this,SLOT(push_button_0()));    connect(ui->button_1,SIGNAL(clicked()),this,SLOT(push_button_1()));    connect(ui->button_2,SIGNAL(clicked()),this,SLOT(push_button_2()));    connect(ui->button_3,SIGNAL(clicked()),this,SLOT(push_button_3()));    connect(ui->button_4,SIGNAL(clicked()),this,SLOT(push_button_4()));    connect(ui->button_5,SIGNAL(clicked()),this,SLOT(push_button_5()));    connect(ui->button_6,SIGNAL(clicked()),this,SLOT(push_button_6()));    connect(ui->button_7,SIGNAL(clicked()),this,SLOT(push_button_7()));    connect(ui->button_8,SIGNAL(clicked()),this,SLOT(push_button_8()));    connect(ui->button_9,SIGNAL(clicked()),this,SLOT(push_button_9()));    connect(ui->button_point,SIGNAL(clicked()),this,SLOT(push_button_point()));    connect(ui->button_left,SIGNAL(clicked()),this,SLOT(push_button_left()));       connect(ui->button_right,SIGNAL(clicked()),this,SLOT(push_button_right()));     connect(ui->button_add,SIGNAL(clicked()),this,SLOT(push_button_add()));           connect(ui->button_minus,SIGNAL(clicked()),this,SLOT(push_button_minus()));       connect(ui->button_ride,SIGNAL(clicked()),this,SLOT(push_button_ride()));         connect(ui->button_divide,SIGNAL(clicked()),this,SLOT(push_button_divide()));     connect(ui->button_equal,SIGNAL(clicked()),this,SLOT(push_button_equal()));       connect(ui->button_AC,SIGNAL(clicked()),this,SLOT(push_button_AC()));    connect(ui>button_CE,SIGNAL(clicked()),this,SLOT(push_button_CE()));

4,按键输入处理函数。主要注意的就是(),+,-,*,/,小数点的输入,数字输入主要注意0的输入即可,下方是详细代码。仔细看一下应该就可以懂得,没有很多复杂的操作,都是字符串和逻辑的操作。

/*数据按键输入*/void Calculator::push_button_0(){    if(put_ctrl.new_put == "0"){        put_ctrl.new_put = "0";        put_ctrl.update_flag = 1;    }    else        put_ctrl.new_put += "0";    ui->put_data->setText(put_ctrl.new_put);}void Calculator::push_button_1(){    if(put_ctrl.new_put == "0")        put_ctrl.new_put = "1";    else        put_ctrl.new_put += "1";    ui->put_data->setText(put_ctrl.new_put);}void Calculator::push_button_2(){    if(put_ctrl.new_put == "0")        put_ctrl.new_put = "2";    else        put_ctrl.new_put += "2";    ui->put_data->setText(put_ctrl.new_put);}void Calculator::push_button_3(){    if(put_ctrl.new_put == "0")        put_ctrl.new_put = "3";    else        put_ctrl.new_put += "3";    ui->put_data->setText(put_ctrl.new_put);}void Calculator::push_button_4(){    if(put_ctrl.new_put == "0")        put_ctrl.new_put = "4";    else        put_ctrl.new_put += "4";    ui->put_data->setText(put_ctrl.new_put);}void Calculator::push_button_5(){    if(put_ctrl.new_put == "0")        put_ctrl.new_put = "5";    else        put_ctrl.new_put += "5";    ui->put_data->setText(put_ctrl.new_put);}void Calculator::push_button_6(){    if(put_ctrl.new_put == "0")        put_ctrl.new_put = "6";    else        put_ctrl.new_put += "6";    ui->put_data->setText(put_ctrl.new_put);}void Calculator::push_button_7(){    if(put_ctrl.new_put == "0")        put_ctrl.new_put = "7";    else        put_ctrl.new_put += "7";    ui->put_data->setText(put_ctrl.new_put);}void Calculator::push_button_8(){    if(put_ctrl.new_put == "0")        put_ctrl.new_put = "8";    else        put_ctrl.new_put += "8";    ui->put_data->setText(put_ctrl.new_put);}void Calculator::push_button_9(){    if(put_ctrl.new_put == "0")        put_ctrl.new_put = "9";    else        put_ctrl.new_put += "9";    ui->put_data->setText(put_ctrl.new_put);}void Calculator::push_button_point(){    if(put_ctrl.new_put == "0")        put_ctrl.new_put = "0.";    else{        if(-1 == put_ctrl.new_put.indexOf("."))            put_ctrl.new_put += ".";    }    ui->put_data->setText(put_ctrl.new_put);}void Calculator::push_button_left(){    if(put_ctrl.old_put == "0"){        put_ctrl.old_put = "(";        put_ctrl.brackets_cnt ++;    }    else{        put_ctrl.old_put += "(";        put_ctrl.brackets_cnt ++;    }    ui->display->setText(put_ctrl.old_put);}void Calculator::push_button_right(){    if(put_ctrl.brackets_cnt > 0){        QString::iterator p = put_ctrl.old_put.end()-1;        if(*p != ')')            put_ctrl.old_put += put_ctrl.new_put;        put_ctrl.old_put += ")";        put_ctrl.brackets_cnt --;        put_ctrl.new_put = "0";        put_ctrl.update_flag = 0;        ui->display->setText(put_ctrl.old_put);    }}/*+ - * / = 按键输入*/void Calculator::push_button_add(){    if(put_ctrl.old_put == "0"){        put_ctrl.old_put = put_ctrl.new_put;        put_ctrl.old_put += "+";        put_ctrl.new_put = "0";        put_ctrl.update_flag = 0;    }    else{        QString::iterator p = put_ctrl.old_put.end()-1;        if(*p == '+' || *p == '-' || *p == '*' || *p == '/' || *p == '(' ){            if(put_ctrl.new_put == "0"){                if(put_ctrl.update_flag){                    put_ctrl.old_put += put_ctrl.new_put;                    put_ctrl.old_put += "+";                    put_ctrl.new_put = "0";                    put_ctrl.update_flag = 0;                }            }else{                put_ctrl.old_put += put_ctrl.new_put;                put_ctrl.old_put += "+";                put_ctrl.new_put = "0";                put_ctrl.update_flag = 0;            }        }else if(*p == ')') {            put_ctrl.old_put += "+";        }    }    ui->display->setText(put_ctrl.old_put);}void Calculator::push_button_minus(){    if(put_ctrl.old_put == "0"){        put_ctrl.old_put = put_ctrl.new_put;        put_ctrl.old_put += "-";        put_ctrl.new_put = "0";        put_ctrl.update_flag = 0;    }    else{        QString::iterator p = put_ctrl.old_put.end()-1;        if(*p == '+' || *p == '-' || *p == '*' || *p == '/' || *p == '(' ){            if(put_ctrl.new_put == "0"){                if(put_ctrl.update_flag || *p == '('){                    put_ctrl.old_put += put_ctrl.new_put;                    put_ctrl.old_put += "-";                    put_ctrl.new_put = "0";                    put_ctrl.update_flag = 0;                }            }else{                put_ctrl.old_put += put_ctrl.new_put;                put_ctrl.old_put += "-";                put_ctrl.new_put = "0";                put_ctrl.update_flag = 0;            }        }else if(*p == ')') {            put_ctrl.old_put += "-";        }    }    ui->display->setText(put_ctrl.old_put);}void Calculator::push_button_ride(){    if(put_ctrl.old_put == "0"){        put_ctrl.old_put = put_ctrl.new_put;        put_ctrl.old_put += "*";        put_ctrl.new_put = "0";        put_ctrl.update_flag = 0;    }    else{        QString::iterator p = put_ctrl.old_put.end()-1;        if(*p == '+' || *p == '-' || *p == '*' || *p == '/' || *p == '(' ){            if(put_ctrl.new_put == "0"){                if(put_ctrl.update_flag){                    put_ctrl.old_put += put_ctrl.new_put;                    put_ctrl.old_put += "*";                    put_ctrl.new_put = "0";                    put_ctrl.update_flag = 0;                }            }else{                put_ctrl.old_put += put_ctrl.new_put;                put_ctrl.old_put += "*";                put_ctrl.new_put = "0";                put_ctrl.update_flag = 0;            }        }else if(*p == ')') {            put_ctrl.old_put += "*";        }    }    ui->display->setText(put_ctrl.old_put);}void Calculator::push_button_divide(){    if(put_ctrl.old_put == "0"){        put_ctrl.old_put = put_ctrl.new_put;        put_ctrl.old_put += "/";        put_ctrl.new_put = "0";        put_ctrl.update_flag = 0;    }    else{        QString::iterator p = put_ctrl.old_put.end()-1;        if(*p == '+' || *p == '-' || *p == '*' || *p == '/' || *p == '(' ){            if(put_ctrl.new_put == "0"){                if(put_ctrl.update_flag){                    put_ctrl.old_put += put_ctrl.new_put;                    put_ctrl.old_put += "/";                    put_ctrl.new_put = "0";                    put_ctrl.update_flag = 0;                }            }else{                put_ctrl.old_put += put_ctrl.new_put;                put_ctrl.old_put += "/";                put_ctrl.new_put = "0";                put_ctrl.update_flag = 0;            }        }else if(*p == ')') {            put_ctrl.old_put += "/";        }    }    ui->display->setText(put_ctrl.old_put);}void Calculator::push_button_equal(){    if(put_ctrl.old_put == "0"){        push_button_AC();        return;    }    else{        QString::iterator p = put_ctrl.old_put.end()-1;        if(*p == '+' || *p == '-' || *p == '*' || *p == '/' || *p == '(' ){            put_ctrl.old_put += put_ctrl.new_put;            if(put_ctrl.brackets_cnt > 0){                for(int i = 0 ; i < put_ctrl.brackets_cnt ; i++)                    put_ctrl.old_put += ")";            }            put_ctrl.new_put = "0";            put_ctrl.update_flag = 0;        }else if(*p == ')') {            if(put_ctrl.brackets_cnt > 0){                for(int i = 0 ; i < put_ctrl.brackets_cnt ; i++)                    put_ctrl.old_put += ")";            }            put_ctrl.new_put = "0";            put_ctrl.update_flag = 0;        }    }    calculate_result(put_ctrl.old_put);    put_ctrl.old_put = "0";    put_ctrl.brackets_cnt = 0;    put_ctrl.update_flag = 0;    put_ctrl.new_put = "0";}void Calculator::push_button_CE(){    put_ctrl.old_put = "0";    ui->display->clear();}void Calculator::push_button_AC(){    put_ctrl.old_put = "0";    put_ctrl.new_put = "0";    put_ctrl.brackets_cnt = 0;    put_ctrl.update_flag = 0;    ui->display->clear();    ui->put_data->setText(put_ctrl.new_put);}

5,获得的表达式如何计算。这里贴下计算的源码,详细的下篇博客分析一下。

/*获取操作符优先级*/int Calculator::Priority(QString data){    int priority;    if(data == "(")        priority = 1;    else if(data == "+" || data == "-")        priority = 2;    else if(data == "*" || data == "/")        priority = 3;    else if (data == ")")        priority = 4;    else        priority = -1;    return priority;}/*将表达式的数据,操作符分割,依次存入mask_buffer数组中*/int Calculator::mask_data(QString expression, QString *mask_buffer){    int i,k = 0,cnt = 0;    QString::iterator p = expression.begin();    int length = expression.length();    for(i = 0 ; i < length ; i += cnt,k++)    {        cnt = 0;        if(*p >= '0' && *p <= '9')        {            QString temp = *p;            p ++;            cnt ++;            while((*p >= '0' && *p <= '9') || *p == '.')            {                temp += *p;                p++;                cnt ++;            }            mask_buffer[k] = temp;        }else{            QString temp = *p;            p++;            cnt ++;            mask_buffer[k] = temp;        }    }    return k;}/*将获取到的分割好的表达式数组,转化为逆波兰表达式,存入数组repolish中*/int Calculator::re_polish(QString *mask_buffer,QString *repolish,int length){    QStack<QString> st2;    int i = 0;    for(int j = 0 ; j < length ; j++)    {        if(mask_buffer[j] != "(" && mask_buffer[j] != ")" && mask_buffer[j] != "+" && mask_buffer[j] != "-" && mask_buffer[j] != "*" && mask_buffer[j] != "/" )            repolish[i++] = mask_buffer[j];        else if(mask_buffer[j] == "("){            st2.push(mask_buffer[j]);        }        else if(mask_buffer[j] == ")"){            while(st2.top() != "(")            {                repolish[i++] = st2.top();                st2.pop();            }            if(st2.top() == "(")                st2.pop();        }        else if(st2.empty() || Priority(mask_buffer[j]) > Priority(st2.top()))            st2.push(mask_buffer[j]);        else{            while(Priority(mask_buffer[j]) <= Priority(st2.top()))            {                repolish[i++] = st2.top();                st2.pop();                if(st2.empty())                    break;            }            st2.push(mask_buffer[j]);        }    }    while(!st2.empty())    {        repolish[i++] = st2.top();        st2.pop();    }    return i;}/*计算逆波兰表达式值并显示*/double Calculator::repolish_calculat(QString *repolish,int length){    QStack <double> st;    for(int m = 0 ; m < length ; m ++)    {        if(repolish[m] != "+" && repolish[m] != "-" && repolish[m] != "*" && repolish[m] != "/" )        {            st.push(repolish[m].toDouble());        }        else        {            if(repolish[m] == "+")            {                double a = st.top();                st.pop();                double b = st.top();                st.pop();                st.push(b + a);            }            else if(repolish[m] == "-")            {                double a = st.top();                st.pop();                double b = st.top();                st.pop();                st.push(b - a);            }            else if(repolish[m] == "*")            {                double a = st.top();                st.pop();                double b = st.top();                st.pop();                st.push(b * a);            }            else if(repolish[m] == "/")            {                double a = st.top();                st.pop();                double b = st.top();                st.pop();                if(a != 0)                   st.push(b/a);                else                {                    ui->display->clear();                    ui->put_data->setText("0 不能做除数");                    return -1;                }            }        }    }    QString res = QString::number(st.top(),'g',10);    ui->display->clear();    ui->put_data->setText(res);    return st.top();}/*表达式计算整合*/void Calculator::calculate_result(QString expression){    QString mask_buffer[100]={"0"},repolish[100]={"0"};    int length = mask_data(expression,mask_buffer);    length = re_polish(mask_buffer,repolish,length);    double result = repolish_calculat(repolish,length);}

6,源码包。
为了方便,我这里将整个工程打包,大家如果需要的话可以下载。还有很多不足之处,希望一起交流,进步。
链接:http://pan.baidu.com/s/1i5R67zv 密码:dd9s

阅读全文
1 0
原创粉丝点击