这次结对编程目的是完成一个带UI的小初高数学学习软件,在原先个人项目的基础增加的功能有:

  1. 实现注册、登录功能,保存用户数据
  2. 用户可修改密码
  3. 用户在做题过程中,题目一题一题出现且有四个选项
  4. 系统需根据用户做题正确性最后给出评分
  5. 软件要带UI

一、用qt构建UI界面

  由于我们选用C++作为完成这个项目的语言,在学长的推荐下用qt来做界面。因为之前没做过界面,也没用过qt,所以上手qt花了不少时间。第一天看qt教程的视频看到自闭,因为b站的教程过于详细,没有时间全部看完,跳着看又抓不住重点,所以看了几集就试着搭起来界面。在这一步之前,我建议对软件的界面流程先规划好,然后再把一个个界面建起来。下面是初学时比较懵逼的地方:

  • 界面间的跳转,通过信号与槽实现。
  • 界面中按键的功能实现,可以通过在“设计”界面中选择控件然后右键“转为槽”,填写槽函数实现。
  • 后来在优化界面的时候发现qt居然有qss,就跟css差不多吧,我们可以直接在“设计”界面中,改写样式表,格式也跟css几乎一模一样
  • 在给界面插入背景图时会出现运行时界面背景图不显示,并且影响了控件的背景图,这个的话不建议在设计中添加界面背景,可以在界面cpp构造函数中增加以下代码:
    QImage image1;
    image1.load("../myItem/子背景.png");
    QImage image2 = image1.scaled(911,577);
    setAutoFillBackground(true);
    QPalette pal = this->palette();
   //  pal.setColor(QPalette::image, QColor(19, 54, 118));这是设置背景色
    pal.setBrush(backgroundRole(), QBrush(image2));
    setPalette(pal);

二、式子计算正确答案,并且计分

在个人项目中,只要出式子不用计算正确答案,但这次结对编程需要给答题计分所以需要计算出正确结果。

我们是先将初高中式子中的‘^2’'^1/2''sin'等先计算完成,再进行四则运算,其中四则运算采用网上的中缀表达式来做运算,附四则运算代码(可计算括号情况、小数、负数)

  1 #include "tcal.h"
  2 #include <bits/stdc++.h>
  3 #include <QString>
  4 #include <QChar>
  5 #include <QByteArray>
  6 #include <QDebug>
  7 #include <qmath.h>
  8 using namespace std;
  9 extern QString s;
 10 extern double Tresult;
 11 stack<double>val;
 12 stack<char>symbol;
 13 QByteArray byte;
 14 tcal::tcal()
 15 {
 16 
 17 }
 18 
 19 tcal::~tcal()
 20 {
 21 
 22 }
 23 //操作符之间的优先级的比较
 24 char tcal::cmp(char a,char b){
 25 //右括号不会进栈,不必写右括号的优先级
 26 //遇到右括号就弹出左括号
 27     if(a=='#'){
 28         if(b=='#'){
 29             return '=';
 30         }else{
 31             return '<';
 32         }
 33     }
 34     if(a=='+'||a=='-'){
 35         if(b=='*'||b=='/'||b=='('){
 36             return '<';
 37         }else{
 38             return '>';
 39         }
 40     }
 41     if(a=='*'||a=='/'){
 42         if(b=='('){
 43             return '<';
 44         }else{
 45             return '>';
 46         }
 47     }
 48     if(a=='('){
 49         if(b==')'){
 50             return '=';
 51         }else{
 52             return '<';
 53         }
 54     }
 55 }
 56 //返回计算结果
 57 double tcal::cal_t(double a,double b,char op){
 58     switch(op){
 59         case '+':
 60             return a+b;
 61         case '-':
 62             return a-b;
 63         case '*':
 64             return a*b;
 65         case '/':
 66             return a/b;
 67     }
 68 }
 69 //表达式计算的过程
 70 void tcal::process(){
 71     symbol.push('#');
 72     uint i=0;
 73     double num = 0.0;
 74     char *c;
 75     QByteArray ba = s.toLatin1();
 76     c = ba.data();//得到字符
 77     int ff = 0;
 78     while(symbol.top()!='#'||i<s.size()){
 79         if(c[i]=='-')
 80         {
 81            ff=1;
 82            ++i;
 83         }
 84         else if(c[i]>='0'&&c[i]<='9'){
 85             //为操作数
 86             num=0;
 87             int f = 0;
 88             while((c[i]>='0')&&(c[i]<='9')||(c[i]=='.')){
 89                 if((i == 0)&&c[i]=='-')
 90                 {
 91                     ff = 1;
 92                 }
 93                 else if((c[i]=='.')||(f != 0))
 94                 {
 95                     if(c[i]!='.')
 96                     {
 97                         num*=10;
 98                         num+=c[i]-'0';
 99                         f++;
100                         ++i;
101                     }
102                     else
103                     {
104                         ++i;
105                         f++;
106                     }
107                 }
108                 else
109                 {
110                     num*=10;
111                     num+=c[i]-'0';
112                     ++i;
113                 }
114             }
115             if(ff == 1)
116             {
117                 num = num*(-1);
118             }
119             ff = 0;
120             if(f!=0)
121             num = num/pow(10,f-1);
122             val.push(num);
123             //cout<<"num="<<num<<endl;
124         }
125         else
126         {
127             switch(cmp(symbol.top(),c[i])){
128                 case '<':
129                     symbol.push(c[i]);
130                     ++i;
131                     break;
132                 case '=':
133                     symbol.pop();
134                     ++i;
135                     break;
136                 case '>':
137                     double a=val.top();
138                     val.pop();
139                     double b=val.top();
140                     val.pop();
141                     val.push(cal_t(b,a,symbol.top()));
142                     //cout<<"a="<<a<<" "<<"b="<<b<<endl;
143                     //cout<<"num="<<val.top()<<endl;
144                     symbol.pop();
145                     break;
146             }
147         }
148     }
149     double res=val.top();
150     val.pop();
151     Tresult = res;
152     return;
153 
154 }

三、短信验证

别问,问就是C++可怜......所以我们用java实现接口,c++调用java的可执行文件发送验证码和手机号给平台。这里是用阿里云的短信服务,腾讯的签名验证比较严格。

四、个人体会

本次项目下来,代码以及修仙能力大大提升,终于做到了一天从早学到晚,仿佛重回高中。做完还是很有成就感的,而且自己做了也才知道很多功能实现并没有想象的复杂。另外,有一点感悟是,敲代码果然是最容易专注的事情了a