这次结对编程目的是完成一个带UI的小初高数学学习软件,在原先个人项目的基础增加的功能有:
- 实现注册、登录功能,保存用户数据
- 用户可修改密码
- 用户在做题过程中,题目一题一题出现且有四个选项
- 系统需根据用户做题正确性最后给出评分
- 软件要带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