【c++】基于Qt实现一个可视化的简易计算器

这个作业属于哪个课程https://bbs.csdn.net/forums/ssynkqtd-05
这个作业要求在哪里https://bbs.csdn.net/topics/617294583
这个作业的目标实现基本功能功能:具有基本功能的计算器
实现加、减、乘、除、归零基本操作。
附加功能:具有科学计算的计算器
实现次方、幂、三角函数等操作。
在博客中使用文字、图片(gif)或者视频的方式展示自己的计算器功能。
其他参考文献https://www.bilibili.com/video/BV1Lh4y1P7PN/?spm_id_from=333.880.my_history.page.click&vd_source=26f8d37993bc2c282ed4952bca067aba

视频展示

无标题视频——使用Clipchamp制作

Gitcode项目地址

https://gitcode.net/m0_62370558/my-Qt-project

PSP表格

PSPPersonal Software Process Stages预估耗时(分钟)实际耗时(分钟)
Planning计划2020
• Estimate• 估计这个任务需要多少时间1510
Development开发12001500
• Analysis• 需求分析 (包括学习新技术)400450
• Design Spec• 生成设计文档6060
• Design Review• 设计复审5070
• Coding Standard• 代码规范 (为目前的开发制定合适的规范)4060
• Design• 具体设计60120
• Coding• 具体编码200240
• Code Review• 代码复审90100
• Test• 测试(自我测试,修改代码,提交修改)300400
Reporting报告150210
• Test Repor• 测试报告80100
• Size Measurement• 计算工作量2020
• Postmortem & Process Improvement Plan• 事后总结, 并提出过程改进计划5090
合计13701730

解题思路描述

要求实现一个简易计算器,要求具有可视的图形化界面。

问题1 选择合适的编译语言和工具

之前从未接触过可视化界面的设计,所以在查询资料后,我选择了Qt这个跨平台的c++开发库,因为它在更易上手的同时官方也在不断更新功能。

问题2 设计与实现过程

在观看了一些视频及博客后,我最终采取了Qt中信号和槽连接的方式,采用cmath库中的函数来进行数学运算。

问题3 单元测试

编写单元测试的代码,确保计算机能够正常工作。参考此链接https://www.cnblogs.com/lsgxeva/p/12564481.html,选取QTest这一Qt自带的测试文件,用**QTest::keyClicks()**这个函数模拟GUI事件,测试案例。
以下链接为Qt官方对于QTest这一头文件的定义,并且Qt5以上的版本都能使用。
https://doc.qt.io/qt-6.4/qtest.html#KeyAction-enum

问题4 打包成exe文件

参考此链接https://blog.csdn.net/2203_75749383/article/details/131770662将vs的项目打包成exe文件

接口设计和实现过程

工具:Qt6.4.3、Visual Studio2022

把所有的按钮放到同一个组中,一起控制,用connect()函数将信号和槽连接到一起。(注:connent()函数在Qt5以下的版本可能会报错)

void Calculator::iniUI()
{
    buttonGroup = new QButtonGroup(this);
    auto btnList = findChildren<QPushButton*>();
    for (auto btn : btnList)
    {
        buttonGroup->addButton(btn);
    }
    connect(buttonGroup, SIGNAL(buttonClicked(QAbstractButton*)), this, SLOT(onButtonGroupClicked(QAbstractButton*)));
    vec.resize(5);
}

关键代码展示

1.按下数字键时输出到结果框中,如果按下数字键时,结果框里已经有了数字,那么将先把这个数字清空,并重置成刚刚按下的数字

 if (name >= "0" && name <= "9" || name == ".")
 {
     if (ui->lineEdit->text() == "0" && name != ".")
     {
         ui->lineEdit->clear();
     }
     if (prevBtn == "+" || prevBtn == "-" || prevBtn == "×" || prevBtn == "÷" || prevBtn == "xⁿ" || prevBtn == "+/-")
     {
         ui->lineEdit->clear();
     }
     ui->lineEdit->insert(name);
 }

2.当按下“=”键时,计算各种运算的结果,并输出到结果框。

else if (name == "=")
{
    vec[2] = val;
    vec[3] = "=";
    if (prevBtn == "+/-" || prevBtn == "=")
    {
        vec[2].clear();
        vec[3].clear();
    }
    if (vec[1] == "+")
    {
        vec[4] = vec[0].toFloat() + vec[2].toFloat();
        ui->lineEdit->setText(vec[4].toString());
    }
    else if (vec[1] == "-")
    {
        vec[4] = vec[0].toFloat() - vec[2].toFloat();
        ui->lineEdit->setText(vec[4].toString());
    }
    else if (vec[1] == "×")
    {
        vec[4] = vec[0].toFloat() * vec[2].toFloat();
        ui->lineEdit->setText(vec[4].toString());
    }
    else if (vec[1] == "÷")
    {
        vec[4] = vec[0].toFloat() / vec[2].toFloat();
        ui->lineEdit->setText(vec[4].toString());
    }
    else if (vec[1] == "^")
    {
        vec[4] = pow(vec[0].toFloat(), vec[2].toFloat());
        ui->lineEdit->setText(vec[4].toString());
    }
    else if (vec[0] == "²√")
    {
        vec[2] = "=";
        vec[3] = sqrt(vec[1].toFloat());
        ui->lineEdit->setText(vec[3].toString());
    }
    else if (vec[0] == "ln")
    {
        vec[2] = "=";
        vec[3] = log(vec[1].toFloat());
        ui->lineEdit->setText(vec[3].toString());
    }
    else if (vec[0] == "sin")
    {
        vec[2] = "=";
        vec[3] = sin(vec[1].toFloat() * 3.1415926 / 180);
        ui->lineEdit->setText(vec[3].toString());
    }
    else if (vec[0] == "cos")
    {
        vec[2] = "=";
        vec[3] = cos(vec[1].toFloat() * 3.1415926 / 180.0);
        ui->lineEdit->setText(vec[3].toString());
    }
    else if (vec[0] == "tan")
    {
        vec[2] = "=";
        vec[3] = tan(vec[1].toFloat() * 3.1415926 / 180.0);
        ui->lineEdit->setText(vec[3].toString());
    }
    else if (vec[0] == "e^")
    {
        vec[2] = "=";
        vec[3] = exp(vec[1].toFloat());
        ui->lineEdit->setText(vec[3].toString());
    }
}

3.用于显示小输入框的代码

ui->lineEdit_2->clear();
for (auto var : vec)
{
    qInfo() << var.toString();
    ui->lineEdit_2->insert(var.toString());
}
prevBtn = name;

性能改进

  • 界面美化
    因为Qt基础的按钮和窗体太过简陋,所以参考一些美化的博客,实现了窗体的颜色替换,按钮的颜色、边框的颜色、鼠标触碰按钮和按下按钮时,按钮的颜色替换、圆角边框等设计
*
{
	border:none;
	
	background-color: rgb(255, 255, 255);
}

QPushButton{
	font: 15pt "微软雅黑";
    color: #2f3640;
    background-color: #f5f6fa;
    border-color: rgb(61,179,255);
    border-radius: 15px;
    border-style: solid;
    border-width: 2px;
    padding: 5px;
}


QPushButton::hover{	
    color: #FFFFFF;
    background-color: rgb(142,200,253);
    border-color:rgb(142,200,253);
}

/**鼠标按压下去的样式**/
QPushButton::pressed,QPushButton::checked{
    color: #FFFFFF;
    background-color: rgb(49,159,254);
}


QPushButton#btn_num_sign,#btn_num_dort,#btn_num_0,#btn_num_1,#btn_num_2,#btn_num_3,#btn_num_4,#btn_num_5,#btn_num_6,#btn_num_7,#btn_num_8,#btn_num_9
{
	font:normal 15pt '微软雅黑';
}


QPushButton#btn_num_is
{
	
	background-color: rgb(0,103,192);
}
QPushButton#btn_num_is:hover
{
	
	background-color: rgb(23,117,197);
}
QPushButton#btn_num_is::pressed,QPushButton#btn_num_is::checked{
    color: #FFFFFF;
    background-color: rgb(49,159,254);
}

*四舍五入保留小数处理
采取将float类型的数据先×100,再调用cmath库中的round()库四舍五入,然后再÷100.00的方法对数据进行处理。

 if (vec[1] == "+")
 {
     vec[4] = vec[0].toFloat() + vec[2].toFloat();
     vec[4] = round(vec[4].toFloat() * 100) / 100.00;
     ui->lineEdit->setText(vec[4].toString());
 }
 else if (vec[1] == "-")
 {
     vec[4] = vec[0].toFloat() - vec[2].toFloat();
     vec[4] = round(vec[4].toFloat() * 100) / 100.00;
     ui->lineEdit->setText(vec[4].toString());
 }

单元测试

简单对加减乘除四个运算做单元测试,均通过。在这里插入图片描述

异常处理

try{
	if(vec[1] == "÷" && vec[2] == "0")
	{
		throw error;
	}
}catch(error){
	ui->lineEdit->setText("ERROR!");
}
else if (vec[1] == "÷")
{
    if (vec[2].toFloat() == 0)
    {
        ui->lineEdit->clear();
        ui->lineEdit->setText("ERROR!");
    }
    else {
        vec[4] = vec[0].toFloat() / vec[2].toFloat();
        vec[4] = round(vec[4].toFloat() * 100) / 100.00;
        ui->lineEdit->setText(vec[4].toString());
    }
}

在这里插入图片描述

心得体会

因为这个作业,我第一次实现了自己开发一个简单的项目——简易计算器。并且为了完整地完成本次作业,我在前期准备时,了解了Qt这个软件地应用和使用方法。 随着一步步跟着作业需求进行,我也一步步收获了许多我以前没有接触到的知识,如何设计一个可视化界面,如何连接信号与槽,如何进行单元测试,如何打包一个小程序,如何进行异常处理······这些收获都将对我之后的学习有所帮助。
而在这个项目中,我也有很多需要更加努力尝试去改进的地方,因为编程能力薄弱,总是有心有余而力不足的情况。在本次项目中,还有一些可能会导致计算机失灵的情况,但是我没有想到好的办法来解决,之后我也会在未来的项目中,多多注意这些问题。

  • 2
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值