【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项目地址
    • PSP表格
    • 解题思路描述
      • 问题1 选择合适的编译语言和工具
      • 问题2 设计与实现过程
      • 问题3 单元测试
      • 问题4 打包成exe文件
    • 接口设计和实现过程
    • 关键代码展示
    • 性能改进
    • 单元测试
    • 异常处理
    • 心得体会

Gitcode项目地址

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

PSP表格

PSP Personal Software Process Stages 预估耗时(分钟) 实际耗时(分钟)
Planning 计划 20 20
• Estimate • 估计这个任务需要多少时间 15 10
Development 开发 1200 1500
• Analysis • 需求分析 (包括学习新技术) 400 450
• Design Spec • 生成设计文档 60 60
• Design Review • 设计复审 50 70
• Coding Standard • 代码规范 (为目前的开发制定合适的规范) 40 60
• Design • 具体设计 60 120
• Coding • 具体编码 200 240
• Code Review • 代码复审 90 100
• Test • 测试(自我测试,修改代码,提交修改) 300 400
Reporting 报告 150 210
• Test Repor • 测试报告 80 100
• Size Measurement • 计算工作量 20 20
• Postmortem & Process Improvement Plan • 事后总结, 并提出过程改进计划 50 90
合计 1370 1730

解题思路描述

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

问题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());
    }
}

【c++】基于Qt实现一个可视化的简易计算器_第1张图片

心得体会

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

你可能感兴趣的:(c++,qt)