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
- QT,计算器实现(四则运算,括号,小数,负数)---(一)
- C++简单计算器实现(四则运算加括号)
- 带括号有负数有小数有表达式的计算器的简单实现
- 科学计算器(可实现带括号的浮点数四则运算)
- 简易计算器(3)- 扩展(支持括号和负数)
- C语言实现 加减乘除四则运算(小数)
- 简易四则运算计算器(C51单片机实现)
- js实现简单计算器(四则运算)
- C语言实现四则运算(小型计算器)
- 字符串四则运算(计算器)
- 【C/C++学院】(14)QT布局/四则运算计算器
- 逆波兰式实现四则运算表达式计算器支持括号、十六进制
- 支持多位数,括号,四则运算,的计算器算法c++实现
- Qt学习笔记(二)---实现四则运算
- 负数的四则运算(重载运算符)
- 计算器C#代码(实现整数的四则运算)
- 使命栈(stack)实现一个简易的四则运算计算器
- 栈实现简单计算器的四则运算(STL)
- secureFX 【文件】could not be opened by servre拒绝访问
- ASM磁盘配置(Oracle RAC 11g)
- 【Android】Material Design应用技术(一)
- bzoj 2118: 墨墨的等式 最短路建模
- [leetcode] 49. Group Anagrams
- QT,计算器实现(四则运算,括号,小数,负数)---(一)
- Android 组件化之路 路由设计
- 自学Java EE 笔记(第二天)
- IO复用——select内核源代码剖析
- 第一章 Thread Management(线程管理) 中
- 欢迎使用CSDN-markdown编辑器
- Gradle构建SpringBoot+Mybatis集成分页插件PageHelper
- sessionStorage 、localStorage 和 cookie 之间的区别
- 如何将谷歌地图发布为 ArcGIS Server 服务