目录
实现功能:加,减,乘,除,取余,小数点,取反(),数字回退,全部清0。
实现功能:加,减,乘,除,取余,小数点,取反(这个最难搞,要兼容前面的),数字回退,全部清0。
一、实现结果(win7的计算器)对比:
win7自带计算器:
我做的:
二、实现思路
1、用QButtonGroup()按钮组让数字按键放入同一个组中,就可以不用写0-9的按钮槽函数,大量节省代码。
2、将加减乘除这些按钮单独定义槽,作用是储存点击的数字和运算符。(误区:这些函数内部并不是实现直接进行运算,而是将运算的数值符号储存。给等号"="槽函数内部计算);
3、定义三个QString类型的变量,第一个是存储大标签的数据,第二个是存储小标签的数据(即右上角顶部那个位置的数据),第三个是标志位,判断是否取反(+-),就在运算减号那里用了一下。
4、需要调用一些QString字符串函数。
三、代码实现
1、首先是将按钮摆放好(双击.ui文件界面)
2、主窗口定义函数
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include "QButtonGroup"
#include <qDebug>
定义一个按钮组对象
QButtonGroup *bg;
QString num="0"; //存储大标签数据
QString num2="0"; //存储小标签数据
QString num3="0"; //标志位
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
ui->setupUi(this);
绑定按钮组
bg = new QButtonGroup(this);
bg->addButton(ui->pushButton_1,1); 添加按钮,用id传递
bg->addButton(ui->pushButton_2,2); 数字按键
bg->addButton(ui->pushButton_3,3);
bg->addButton(ui->pushButton_4,4);
bg->addButton(ui->pushButton_5,5);
bg->addButton(ui->pushButton_6,6);
bg->addButton(ui->pushButton_7,7);
bg->addButton(ui->pushButton_8,8);
bg->addButton(ui->pushButton_9,9);
bg->addButton(ui->pushButton_11,0);
//关联对象按钮,buttonClicked()是内部函数!用于发送id信号。
connect(bg,SIGNAL(buttonClicked(int)),this,SLOT(Calculate(int)));
}
3、接收id槽函数
用来接收id值的函数,即1,2,3,4,5...
void MainWindow::Calculate(int id){
规定输入范围
if(num.length()<10){
最多输入9位,追加数字
num.append(QString::number(id)); 数字转字符串,拼接字符串,不会被覆盖
ui->label->setNum(num.toDouble()); 显示到大标签
}
num = QString::number(num.toDouble()); 数字转字符串,防止多次输入0
ui->label->setText(num); 显示到标签
}
4、运算按钮槽函数,其实都是重复的代码
加
void MainWindow::on_pushButton_12_clicked(){
//只需存储值,不需要计算
num2 = ui->label->text(); //将大标签的数据存入小标签
num2.append("+"); //数据后面拼接一个'+'号,即999+
ui->label_2->setText(num2); //显示到小标签里
//清空数据1
num.clear(); //重点!清空大标签的数据!为了存放下一个输入的值。
}
减
void MainWindow::on_pushButton_13_clicked(){
//只需存储值,不需要计算
num2 = ui->label->text(); //将大标签的数据存入小标签
num2.append("-"); //数据后面拼接一个'-'号,即999-
ui->label_2->setText(num2); //显示到小标签里
//清空数据1
num.clear(); //重点!清空大标签的数据!为了存放下一个输入的值。
}
乘
void MainWindow::on_pushButton_14_clicked(){
num2 = ui->label->text(); //将小标签的数据给num2存储,才能实现连续运算
//只需存储值,不需要计算
num2.append("*"); //小标签数据后面拼接一个'*'号,即999*
ui->label_2->setText(num2); //显示到小标签里
//清空数据1
num.clear(); //重点!清空大标签的数据!为了存放下一个输入的值。
}
除
void MainWindow::on_pushButton_15_clicked(){
//只需存储值,不需要计算
num2 = ui->label->text(); //将大标签的数据存入小标签
num2.append("/"); //数据后面拼接一个'/'号,即999/
ui->label_2->setText(num2); //显示到小标签里
//清空数据1
num.clear(); //重点!!清空大标签的数据!为了存放下一个输入的值。
}
取余,只能取整数
void MainWindow::on_pushButton_20_clicked(){
//只需存储值,不需要计算
num2 = ui->label->text(); //将大标签的数据存入小标签
num2.append("%"); //小标签数据后面拼接一个'%'号,即999%
ui->label_2->setText(num2); //显示到小标签里
//清空数据1
num.clear(); //重点!清空大标签的数据!为了存放下一个输入的值。
}
5、等号运算槽函数
等号
void MainWindow::on_pushButton_16_clicked()
{
num2 = ui->label_2->text(); 取出小标签数据
只判断一次,将数据变成Double型
if(num2.contains("+")){ 加法
num2.remove("+");
ui->label->setNum(num.toDouble()+num2.toDouble());
}
如果只是减法,没有乘和除,则运算。
else if(num2.contains("-")&&(!num2.contains("*"))&&(!num2.contains("/"))){
if(num3.toDouble()<0){ 判断第一个数是否为负,减法,标志位
num2.chop(1); 删掉小标签最后一位的'-'号
ui->label->setNum(num2.toDouble()-num.toDouble());
}else{
num2.remove("-");
ui->label->setNum(num2.toDouble()-num.toDouble());
}
}else if(num2.contains("*")){ 乘法:数据包含正数和负数情况
num2.remove("*");
ui->label->setNum(num2.toDouble()*num.toDouble());
}else if(num2.contains("/")){ 除法
num2.remove("/");
ui->label->setNum(num2.toDouble()/num.toDouble());
}else if(num2.contains("%")){ 取余
num2.remove("%");
ui->label->setNum(num2.toInt()%num.toInt());
}
}
6、其他槽函数
清空数据
void MainWindow::on_pushButton_17_clicked(){
num.clear();
num2.clear();
num3.clear();
ui->label->setNum(0);
ui->label_2->setNum(0);
}
.符号
void MainWindow::on_pushButton_10_clicked(){
if(!num.contains(".")){ 如果num存在.的话就不执行,如果不存在.就执行,即判断是否已存在.符号
num.append("."); 没有输入.符号,那么就加一个
ui->label->setText(num); 显示到标签
}
}
取正负
void MainWindow::on_pushButton_18_clicked(){
QString sum = ui->label->text();
ui->label->setText(sum);
ui->label_2->setText(sum); //显示到小标签里
num3 = sum; //标志位,判断第一个数据是否为负
num3.prepend("-"); //在字符串开头插入"-"号
ui->label->setText(num3); //再次显示
ui->label_2->setText(num3); //显示到小标签里
qDebug() <<"num3" << num3;
}
回退位
void MainWindow::on_pushButton_19_clicked(){
删除右边开始的n个字符
num.chop(1);
ui->label->setText(num);
}
7、头文件,也就一些声明的槽函数
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACE
class MainWindow : public QMainWindow
{
Q_OBJECT
signals:
void button_sig(int a);好像这个信号没用到
public:
MainWindow(QWidget *parent = nullptr);
~MainWindow();
public slots:
void Calculate(int id);
private slots:
加
void on_pushButton_12_clicked();
减
void on_pushButton_13_clicked();
乘
void on_pushButton_14_clicked();
除
void on_pushButton_15_clicked();
等号
void on_pushButton_16_clicked();
void on_pushButton_10_clicked();
void on_pushButton_17_clicked();
void on_pushButton_10_clicked();
void on_pushButton_20_clicked();
void on_pushButton_18_clicked();
void on_pushButton_19_clicked();
private:
Ui::MainWindow *ui;
};
#endif // MAINWINDOW_H
实现效果
计算器演示
总结:
1、先考虑存储问题,先将第一个数据存储到某个对象中,然后清0该对象,存储下一个数据,其实应该定义多个对象存储的,不过逻辑要搞清楚。
2、需要用到QString库函数,看不太懂英文,很多时候需要上网查,关于QT的内容还是很多的。
3、重要的是标签的获取与储存,关于取正负的时候符号一直没想通,后来加个标志位就简单了。
4、信号与槽是QT重要知识点,它由c++实现,几乎都是面向对象的思维,一个大对象派生出一个个小对象,小对象直接也用信号与槽互通。