UI第三组总结 PB16150206朱池苇+PB16070837刘鼎乾

项目简介

    这次软件工程结对项目为制作一个给小学生用的四则运算出题软件,我们分配到的是UI组,也就是负责人机交互使用Core组封装好模块。

    GitHub地址:https://github.com/Ignoramus0817/Calculation-GUI

 

需求分析

  •  对上述各属性参数(生成题目的数量,操作数的数量,题目及答案中的数值的范围……)进行设置
  •  调用Core模块得到题目和运算结果,显示题目,接受输入,并能判断答案是否正确
  •  增加倒计时功能,每个题目必须在20秒内完成,否则,得0分并进入下一题
  •  增加错题记录功能,对于答错的题,将其保存下来,当下次进行复习时,增大错题在练习题中的概率
  •  增加历史纪录功能,把用户做题的成绩纪录下来并可以展现历史纪录
  •  增加成绩分享功能,生成成绩单,想一想成绩单里要展现什么,仅仅是最后的得分吗?错题的类型及数量?帮用户分析其薄弱的环节,提出合理的学习建议?
  •  对所有Core组的模块进行测试

团队分工

     结对编程作业大部分的时间都是采取共同编写代码的方式,即“一个做驾驶员,一个做领航员,驾驶员负责敲键盘,领航员在一侧提供建议、检查错误或帮忙搜索相关的资料。

     就这次团队项目而言,合作比较愉快。清明节的后两天两人一起学习了Qt。由于朱池苇对Qt比较熟悉,所以大部分程序都是朱池苇同学作为驾驶员,而刘鼎乾同学则作为领航员,与朱池苇同学对问题进行讨论,查找资料,检查错误等。博客则由两人共同完成。

 

PSP 表格

PSP2.1任务内容计划完成需要的时间(min)实际完成需要的时间(min)
Estimate估算1515
Analysis需求分析(包括学习)135200
Design Spec设计文档1515
Coding Standard代码规范1010
Design具体设计60120
Coding具体编码300480
Code Review代码复审--(包含在编码过程中) 
Test测试120300
Record Time Spent记录用时1010
Test Report测试报告2040
Size Measurement计算工作量2010
Postmortem总结改进180180
Summary合计8851380

 

代码规范

 

一、命名风格

 

1、文件名:一律小写。

 

2、类名:一律使用UpperCamelCase。

 

3、变量名、对象名、方法名(函数名):一律使用lowerCamelCase。

 

 

 

二、代码风格

 

1、4空格缩进

 

2、左花括号换行

 

3、不同模块代码之间空行

 

4、预处理命令:

 

​ 文件包含:类和头文件分别集中,并且模块之间空格

 

​ 宏定义:宏名一律大写

 

 

 

三、其他

 

1、程序所有内容全部为英文,禁止出现中文和拼音,包括注释和UI界面文字。(博客下方展示代码块中注释是另外添加,程序中不含中文注释)

 

 

代码架构与具体实现

 

     UI界面布局设计由Qt Designer完成,而复杂逻辑则由Qt Creator完成。

 

     UI界面非常简单,由于使用qStackedWidget来实现翻页和题目的刷新,整个UI仅分为三个部分:主窗口CalGUI,存档对话框SaveSuccess,以及历史记录对话框History。绝大部分的功能都在主窗口上实现,存档对话框以及历史记录对话框仅有显示功能,因此着重介绍主窗口的结构和实现。

 

     主窗口上添加StackedWidget控件,分成三页:

 

     第一页:初始化生成条件

 

     本页主要由各种数字输入框(SpinBox)和选项按钮(CheckBox、RadioButton)构成,用SpinBox::valueCheckBox::isCheckedRadioButton::isChecked获取用户输入的值,而通过设定默认值和输入范围的方法,可以限制非法输入。

 

     本页包含两个按钮(PushButton),Next和Cancel,Cancel顾名思义是退出,而Next则是说明已经设定完毕,可以开始做题,因此,Next的槽中调用了Core中的Setting接口。当用户按下Next时,各个参数已经设置完毕。

 

     第二页:显示题目和题号、输入答案、倒计时

 

     本页有两个按钮Start和Next,分别实现“开始”和“下一题”,Next按钮初始状态为隐藏,当Start被按下时显示。Start按钮使第一个题目显示在一个文本浏览框TextBrowser中,并使计时器开始倒计时。

 

     倒计时的实现:

//添加在Start按钮按下信号的槽函数中
void CalGUI::on_startButton_clicked()
{
    QTimer *timer = new QTimer(this);
    connect(timer,&QTimer::timeout,this,&CalGUI::timerUpdate);
    timer->start(1000);
}

//刷新时间的函数
void CalGUI::timerUpdate()
{
    int a=ui->restTime->value();
    if(a>0)
        ui->restTime->display(a-1);
    else
        ui->qNext->clicked();  //如果时间耗尽,发出Next按钮按下的信号,自动跳转至下一题。
}

//timer的信号函数设置为空
void CalGUI::timeOut()
{
}

     Next按钮控制界面的刷新(重新向控件中写入数据即可)以及对错的判断,判断正误,获取LineEdit中字符串,和答案字符串比较即可。若正确,做对的题目加一,若错误,存储至错题部分。

     将Timer的时间耗尽和Next的按下两个信号连接在一起,即可方便地实现时间耗尽自动跳转的功能,由于判断正误由Next控制,因此将两者合并不会造成误判。

     用两个QLabel分别显示当前题号和总题数。在Next槽函数中比较两个QLabel对应数字的大小(Qt提供了相关转换函数,非常方便),当前者大于后者时,进入显示结果页面。

     第三页:显示结果,存档和查看历史记录

     结果显示即为前面做题时存储的正确题目数量、错题、正确率的显示。

     存档按钮控制生成.txt存档文件(由于没有掌握对话框数据传递,偷了个懒不让用户自行输入文件名),历史记录按钮控制查看往期记录(包括时间、正确题目数、总题目数、正确率、错题、错误答案和正确答案)。比较简单。

 

测试结果

 

参数设置页面

 

 

开始答题前

 

开始答题后

 

结果(太难无法口算因此全错)

 

结果2(为了展示错题和正确率统计故意错一半)

 

历史记录对话框

BUG记录与分析

 

    1、LNK2019 无法解析的外部命令

 

     这是编写UI和对接过程中遇到最多的一个BUG。

 

     如果是在编写UI本身过程中遇到,一般是给出了函数声明,但是没有具体实现所导致的,在.h+.cpp这种类定义和成员函数定义分离的情况下,此类错误极易出现。我认为较好的方法是,声明后立刻在cpp文件中撰写函数定义,如果暂且不需要写,可以用花括号留空。

 

     如果是在对接过程中遇到,不可能是相关函数core组同学没有定义。则一般是lib文件没有正常加载,或者是dll文件的属性(位数x86还是x64、debug还是release)与编译环境的属性不匹配所导致的。合理地发布SDK就能解决这种问题,所谓合理,指的是发布时分类,并且指明相应SDK的属性。

 

 

 

    2、无法打开xxxx.lib文件

 

    这是库文件没有正常加载导致的,Qt Creator中.lib文件的加载方式和VS中有所不同,需要在.pro文件中新增格式如下的代码:

LIBS +=-L$$quote(D:\zhu\Software Engineering\2018-SE-Course\Calculator GUI\CalGUI\untitled\Core15\x64) -lCore15
或
LIBS +=-LD:\zhu\SoftwareEngineering\2018-SE-Course\CalculatorGUI\CalGUI\untitled\Core15\x64 -lCore15

     其中-L后接.lib文件的绝对路径,-l后接.lib文件不加拓展名的文件名。如果路径中含有括号,应该使用$$quote()将路径括起。

     值得注意的是,假如需要将源代码发给他人,此处绝对路径需要修改为相对路径,否则无法正常加载。

     许多组发布SDK时仅仅注明了Qt for VS的使用方法,而忽略了Qt Creator的使用方法。

 

    3、函数参数表无法将xxx转换为xxx

     这种BUG本是函数传入的参数和参数表不一致导致的,是编程时出现的失误,为何要在此处列出呢?因为Qt虽然支持部分C++库和语法,但两者仍然有区别。

     比如Qt中的字符串类为QString,而C++中类为string(std::string),需要经过QString::fromStdString转换,才可以使用。

     这种差异的存在导致对接过程中此类BUG大量出现,小心一些即可避免。

 

在与第七组对接后的BUG和解决方案:

 

    1、显示结果页面正确率和正确题数显示不正常(由于计时器信号未阻塞,会导致正确题目数量不断增加,又由于正确率为实时计算,因此正确率也会不断增加),跳至结果页面后,阻塞计时器信号即可解决。

 

 

    2、分辨率问题,控件无法自适应窗口大小和分辨率。修改UI布局可以解决(推荐刚开始编写UI时就考虑这个问题,否则会产生巨大的工作量)。

 

 

 

 

    3、运行时有命令行(见上图),修改Qt设置文件,将CONFIG += console改为CONFIG += release即可。

 

由编程得出的一些建议

     1、发布SDK时一定要根据编译环境和平台分类。

     2、勤于写README,并且在写README时要考虑各种用户的需求(比如VS用户和Qt Creator用户)。

     3、接口越少越好(接口数和参数数量折中)。

 

工作时刻

 

结对编程的意义相关 

  • 一个人编写代码,总是有种灯下黑的现象。一些非常简单的错误,由驾驶员自己是很难检查出来的,旁观者清,领航员则能够较为轻易地发现。
  • 结对编程相当于在编写代码的同时,进行复审,这可以使驾驶员能够“朝着目标方向”前进,代码规范、算法思想、以及最重要的,概念完整性,可以得到保障。
  • 可以不断从别人那里学习,提高自己的水平。在他人的监督下写代码有利于形成良好的代码风格,清晰的编码思路,以及熟练的调试技巧等
  • 两个人的知识结构可以互补,比如驾驶员拥有稳重的编程风格和严谨的代码规范,但不善于设计巧妙的算法;而领航员则有灵活的头脑,两者结合,可以使代码高效、优雅而不失严谨,不会成为“奇技淫巧”。

关于走上工作岗位后是否会选择结对编程

刘鼎乾)我认为我会选择结对编程。不仅是因为队友之间能相互找到彼此的灯下黑,还因为能在工作之余和别人进行交流,切磋。这也是不断提高自己,终身学习的有效途径。

朱池苇在工程需要迅速完成且规模不大时,我不会选择结对编程;但在工作量大的工程中,结对编程无疑是有其意义的。工程较大时,思路容易混乱,或者因为繁琐的各种定义而犯一些低级的错误。结对编程大大减少了这方面的成本。

 

课程建议:

  (刘鼎乾我认为邓老师确实非常非常负责,很认真地想把这门课上好,但是我觉得还是有一些问题。

      1、上课不只是讲软件工程的理论,还希望能多讲一些实际编程有关的东西。
      2、安排大作业和结对编程的时候,尽量和期中考等考试分开,能不影响大家的gpa就不影响。希望后面补做个人作业和结对编程时,不要放在和期末考冲突的时候,可以考虑放在暑假。
      3、我觉得为了难而难是不可取的。有些时候加大难度我感觉不是很有现实意义。而我们工科是非常讲究现实意义的。增加难度可以,但要建立在实际有用的基础上,如果为了难为我们而故意弄一些很繁琐的事情,我觉得并不可取。

 

  (朱池苇目前我选这门课的目的基本上都实现了:了解自己技术栈的缺陷、体验一下稍难一些的工程、磨炼编程技术和肝功能(逃)。因此意见也不多。主要如下:

  希望能具体介绍一下哪种工程师需要精通哪些技能(比如:前端工程师必须精通HTMLXML,JSCSSjsonajax等等),使我们课外自己学习更有方向性,我在这方面比较迷茫,哪些东西是会有用的,它们是用来干嘛的。如果能推荐一些教材或者学习时可以设定的目标等等就更好了。

 

团队项目如何改进    

  与结对编程类似,一个团队中一般都有所谓“架构师”“产品负责人”的存在,这些人对技术或是需求非常了解,他们应该成为团队的领航员,由他们规定工程的架构和规范,所有人需要根据他们设定的规则完成自己的工作。

  而复审工作则不是同时进行的,而是完成一个部分后将代码交由领航员审核,对其中不恰当的部分进行修正。

  同时组内工作职能相近的同学也可以采用标准的结对编程方式。

 

 

转载于:https://www.cnblogs.com/Ignoramus/p/8852549.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值