软件工程实践作业1-Qt实现可视化计算器

目录

Gitcode项目地址

界面展示

PSP表格

解题思路描述

问题1

问题2

问题3

接口设计和实现过程

关键代码展示

性能改进

单元测试

异常处理

心得体会

这个作业要求在哪里 https://bbs.csdn.net/topics/617294583
这个作业的目标 完成一个具有可视化界面的计算器
其他参考文献

1.qt按钮样式_qt按钮样式表-CSDN博客

2.QT打包成一个exe文件。(多种方法)-CSDN博客

Gitcode项目地址

072103308-贺心悦 / QT-CALCULATOR · GitCode

界面展示

软件工程实践作业1-Qt实现可视化计算器_第1张图片

PSP表格

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

解题思路描述

选用了Qt6+vs2022联合开发,基于c++语言,设计一个可视化界面,通过点击计算器界面上的按钮输入一个表达式,通过逆波兰表达式算法算出表达式的值,输出在可视化界面上。

问题1

如何实现可视化界面和计算函数的连接。

问题2

如何美化可视化界面,修改可视化界面的颜色、形状、字体等。

问题3

如何将项目打包导出。

接口设计和实现过程

Qt自带了button组件,可通过设计ui界面设计按键,然后通过连接点击信号和槽函数,直接点击button就可以形成输入。

Qt自带的ui类,通过connect函数实现连接。

//Widget类
namespace Ui {
    class Widget;
}
//一个连接函数案例,将divButton和实现输入一个÷符号的功能函数连接起来
connect(ui->divButton, SIGNAL(clicked()), this, SLOT(on_divButton_clicked()));

关键代码展示

该部分实现的是按下按钮,往要计算的表达式里加入该按钮的符号,并把该符号显示在界面上,以按下按钮“1”为例。

private slots:
    void on_oneButton_clicked();

void Widget::on_oneButton_clicked()
{
    expression += "1";
    display += "1";
    ui->mainLineEdit->setText(display);

}

按下等于号,计算表达式,显示出计算结果,使用的是逆波兰表达式算法。

void Widget::on_equalButton_clicked()
{
    QStack s_num;
    QStack s_opt;

    char opt[128] = {0};
    int i = 0;
    int numDigits=0;
    double tmp = 0, num1, num2;

    //把QString转换成char *
    QByteArray ba;
    ba = expression.toLatin1();         //把QString转换成QByteArray
    strcpy(opt, ba.data());  //data可以把QByteArray转换成const char *

    while (opt[i] != '\\0' || s_opt.empty() != true)
    {
        if (opt[i] >= '0' && opt[i] <= '9')
        {
            tmp = tmp * 10 + opt[i] - '0';
            i++;
            if (opt[i] < '0' || opt[i] > '9')
            {
                s_num.push(tmp);
                tmp = 0;
            }
        }
        else if (opt[i] == 'p') //输入π,e同理,省略
        {
            s_num.push(M_PI);
            i++;
            continue;
        }

        else           //操作符
        {
            if (s_opt.empty() == true || Priority(opt[i]) > Priority(s_opt.top()) ||
                    (s_opt.top() == '(' && opt[i] != ')'))
            {
                s_opt.push(opt[i]);
                i++;
                continue;
            }

            if (s_opt.top() == '(' && opt[i] == ')')
            {
                s_opt.pop();
                i++;
                continue;
            }

            if (Priority(opt[i]) <= Priority(s_opt.top()) || (opt[i] == ')' && s_opt.top() != '(') ||
                (opt[i] == '\\0' && s_opt.empty() != true))
            {
                char ch = s_opt.top();
                s_opt.pop();
                switch(ch)
                {
                   //以加法为例,其他算数符省略
                    case '+':
                        num1 = s_num.top();
                        s_num.pop();
                        num2 = s_num.top();
                        s_num.pop();
                        s_num.push(num1 + num2);
                        break;
                   
                }
            }
        
        }
    }

    ui->mainLineEdit->setText(QString::number(s_num.top()));
    display += '=';
    ui->disLineEdit->setText(display);
    expression.clear();
}

int Widget::Priority(char ch)
{
    switch(ch)
//设置各符号优先级
    {
        case' ':
            return 5;
        case '(':
            return 4;
        case' ':
            return 3;
        case ' '::
            return 2;
        case '+':
            return 1;
        default:
            return 0;
    }
}

按钮的样式设计代,以按钮“1”为例。

//正常情况下样式
QPushButton{
	font: 15pt "黑体";;
    color: rgb(0, 0, 0);
    background-color:rgb(255, 255, 255) ;
    border-color: rgb(230, 231, 233);
    border-radius: 10px;
    border-style: solid;
    border-width: 1px;
    padding: 2px;
}
//鼠标停留在按钮上的样式
QPushButton::hover{	
    color: rgb(0, 0, 0);
    background-color: rgb(221, 240, 255);
    border-color: rgb(143, 186, 255);
}
//标按压下去的样式
QPushButton::pressed,QPushButton::checked{
    color: #FFFFFF;
    background-color: rgb(75, 111, 189)
}

性能改进

在完成了基础四则运算的功能后,加入了三角函数,对数,幂等更多运算功能。

单元测试

软件工程实践作业1-Qt实现可视化计算器_第2张图片

异常处理

对于除数等于0的情况,在结果框里显示“ERROR”。

软件工程实践作业1-Qt实现可视化计算器_第3张图片

对于计算sin(π)时,会得出一个e-16数量级的数,考虑到π在运算过程中的精度可能会损失的问题,最后在答案数上进行一个判断,如果一个数趋近于0那么就视为0。

if (s_num.top() < 1.0e-10 && s_num.top() >= 0) 
    s_num.top() = 0;

软件工程实践作业1-Qt实现可视化计算器_第4张图片

心得体会

在拿到这个任务后,上网查找了许多关于可视化实现的方法,最后基于对美观度和语言的考量选择了使用Qt(基于c++),在经过学习Qt的基础功能后开发了一个简单的计算器,再逐步的追加了更多的计算功能,并且学习了然后美化界面,对计算器界面进行了一点设计。在开发过程中发现使用c++计算表达式较为复杂,不像Python有eval函数能计算数学表达式,在最初选择语言的时候还是欠缺考虑,不过好在Qt在ui界面的设计上非常方便且好学。同时,也遇到了很多问题,尤其是程序的测试和打包,因为以前没有类似的经验,所以上网查了很多资料一直在不断的试错,这些对我的对软件工程的理解和领悟有了较大的帮助。

由于时间及能力有限,所以该计算器只能计算没有错误的数学表达式,很多细节都还没有处理,例如对错误表达式(如使用sin没加右括号)的判断和报错,不支持输入“00000”这种数字,不支持计算隐藏乘号的情况(如sin3π)等等,希望未来有机会能进一步做优化。总之,这次的作业让我体验了完整的项目开发流程,我会将在这个项目中得到的经验总结并加以运用到未来的项目中去,不断提高自己的能力。

你可能感兴趣的:(c++,qt6.3)