【QT 网络云盘客户端】——登录界面功能的实现
目录
1.注册账号
2.服务器ip地址和端口号设置
3. 登录功能
4.读取配置文件
5.显示主界面
1.注册账号
1.点击注册页面,将数据 输入 到 用户名,昵称,密码,确认密码,手机,邮箱 的输入框中,
点击确定,触发槽函数 on_reg_but_clicked。
2.on_reg_but_clicked 会校验 各个输入框中数据格式 的合法性,比如说手机号只能由数字组成。
使用正则表达式进行检验
3.如果数据没问题,则客户端发送一个http请求给服务器:
POST http://119.23.41.13:80/register HTTP/1.1
Content-Type: application/json{"email": "sjp3250506022@qq.com", //邮箱"firstPwd": "e10adc3949ba59abbe56e057f20f883e",//密码,用md5值进行加密"nickName": "lisi", //昵称"phone": "13727989171", //电话号码"userName": "lisi" //用户名
}
服务器响应:
"code": "002" //账号注册成功
"code": "003" //用户已经存在
"code": "004" //账号注册失败
实现:
//注册框的流程
void Dialog::on_reg_but_clicked()
{/*1.获取输入框中的数据2.校验数据格式是否正确3.封装http请求,发送http请求4.接收http响应,处理http响应*/QString usr=ui->usr_edit->text();QString nickname=ui->nickname_edit->text();QString password=ui->pasword_edit2->text();QString confirmpassword=ui->confirm_edit->text();QString mail=ui->mailbox_edit->text();QString phone=ui->phone_edit->text();QRegExp reg(USER_REG);//校验账号的规则if(!reg.exactMatch(usr)){//校验失败QMessageBox::warning(this,"警告","输入的账号格式有误");return;}reg.setPattern(PASSWD_REG);if(!reg.exactMatch(password)){QMessageBox::warning(this,"警告","输入的密码格式有误");return;}reg.setPattern(EMAIL_REG);if(!reg.exactMatch(mail)){QMessageBox::warning(this,"警告","输入的邮箱格式有误");return;}reg.setPattern(PHONE_REG);if(!reg.exactMatch(phone)){QMessageBox::warning(this,"警告","输入的手机号码格式有误");return;}if(confirmpassword!=password){QMessageBox::warning(this,"警告","确认密码不匹配");return;}//QNetworkAccessManager* manger=new QNetworkAccessManager();//封装http请求QNetworkRequest request;//从配置文件中获取到ip地址和port端口号QString ip=Common::getInstant()->getConfValue("web_server","ip");QString port=Common::getInstant()->getConfValue("web_server","port");QString url=QString("http://%1:%2/register").arg(ip).arg(port);request.setUrl(QUrl(url));//设置文件类型request.setHeader(QNetworkRequest::ContentTypeHeader,QVariant("application/json"));//将data数据以QJson的格式发送给服务器QJsonObject object;object.insert("email", mail);//邮箱object.insert("userName", usr);//账号object.insert("phone", phone);object.insert("nickName", nickname);object.insert("firstPwd", m_common->getStrMd5(password));QJsonDocument doc(object);QByteArray data=doc.toJson();//发送数据QNetworkReply* rely=manger->post(request,data);connect(rely,&QNetworkReply::readyRead,this,[=]{//响应到达,读取所有的数据QByteArray s=rely->readAll();qDebug() << "服务器返回数据:" << QString(s);//将s数据转换为Json对象QJsonParseError err;QJsonDocument document=QJsonDocument::fromJson(s,&err);if(err.error!=QJsonParseError::NoError){qDebug()<<"QJson格式错误";return;}//将QJson字符串转换为QJson对象QJsonObject object1;object1=document.object();//获取状态码QString value1=object1["code"].toString();if(value1=="002"){QMessageBox::information(this,"提示","账号注册成功");}if(value1=="003"){QMessageBox::warning(this,"警告","该账号已经存在");}if(value1=="004"){QMessageBox::critical(this,"注册失败","注册失败");}rely->deleteLater();});
}
2.服务器ip地址和端口号设置
1.点击 确定 按钮,获取服务器 ip 和端口号的 信息
2.验证服务器 和 端口号的格式,如果验证成功,将 服务器的 ip地址和 端口号写入到 cfg.json 配置文件中。
//点击服务器设置页的按钮,将ip地址和端口写入到配置文件中
void Dialog::on_ok_button_clicked()
{QString ip=ui->ip_edit->text();QString port=ui->port_eidt->text();QRegExp reg(IP_REG);//校验账号的规则if(!reg.exactMatch(ip)){//校验失败QMessageBox::warning(this,"警告","输入的IP地址有误");return;}reg.setPattern(PORT_REG);//校验账号的规则if(!reg.exactMatch(port)){//校验失败QMessageBox::warning(this,"警告","输入的端口号有误");return;}m_common->writeWebInfo(ip,port);QMessageBox::warning(this,"提示","配置成功");ui->stackedWidget->setCurrentWidget(ui->login_page);return;
}// 将服务器的ip和port写入到配置文件
void Common::writeWebInfo(QString ip, QString port, QString path)
{QMap<QString,QVariant> web_server;web_server.insert("ip",ip);web_server.insert("port",port);QString usr_base64=getConfValue("login","user");QString pwd_base64=getConfValue("login","pwd");QString remember=getConfValue("login","remember");QMap<QString,QVariant> login;login.insert("user",usr_base64);login.insert("pwd",pwd_base64);login.insert("remember",remember);QMap<QString, QVariant> json;json.insert("web_server", web_server);json.insert("login", login);QJsonDocument jsonDocument = QJsonDocument::fromVariant(json);if ( jsonDocument.isNull() == true){qDebug() << "QJsonDocument::fromVariant错误";return;}QFile file(CONF_FILE);if(!file.open(QFile::WriteOnly)!=0){qDebug()<<"打开文件失败";return;}file.write(jsonDocument.toJson());file.close();qDebug()<<"配置成功";
}
3. 登录功能
1.点击登录,获取用户名和密码
2.验证 用户名 和密码 格式的 合法性,如果 合法,则发送一个http请求给服务器:
POST http://119.23.41.13:80/login HTTP/1.1
Content-Type: application/json{"pwd": "e10adc3949ba59abbe56e057f20f883e", //密码,用md5进行加密"user": "zhangsan" //用户名
}
http响应:
//登录成功的响应
HTTP/1.1 200 OK{"code": "000","token": "86569b8a537abf45acbb811f0244a69e"
}//登录失败的响应
HTTP/1.1 200 OK{"code": "001",
}
登录成功后:
1.客户端需要保存token,因为客户端接下来访问服务器 都需要 加上token来验证身份
2.创建一个 logininfoinstance 实例对象,将 用户名 ,token,服务器ip 和 端口号保存到logininfoinstance中,方便后续进行读取
3..需要 将用户的 用户名 和密码 写入到 cfg.json文件 中。为了防止泄密,需要对用户名和密码进行二次加密,先进行desc加密,然后再进行base64加密
4.创建主界面,显示主界面
代码实现:
//登录按钮
void Dialog::on_login_toolButton_clicked()
{qDebug()<<"登录";//获取账号密码QString account=ui->account_edit->text();QString password=ui->password_edit->text();//QRegExp reg(USER_REG);//校验账号的规则if(!reg.exactMatch(account)){//校验失败QMessageBox::warning(this,"警告","输入的账号格式有误");return;}reg.setPattern(PASSWD_REG);if(!reg.exactMatch(password)){QMessageBox::warning(this,"警告","输入的密码格式有误");return;}//封装http请求QNetworkRequest request;//从配置文件中获取到ip地址和port端口号QString ip=Common::getInstant()->getConfValue("web_server","ip");QString port=Common::getInstant()->getConfValue("web_server","port");QString url=QString("http://%1:%2/login").arg(ip).arg(port);//设置登录的urlrequest.setUrl(QUrl(url));//设置文件类型request.setHeader(QNetworkRequest::ContentTypeHeader,QVariant("application/json"));//将data数据以QJson的格式发送给服务器QJsonObject object;object.insert("user", account);object.insert("pwd", m_common->getStrMd5(password));QJsonDocument doc(object);QByteArray data=doc.toJson();//发送数据QNetworkReply* rely=manger->post(request,data);connect(rely,&QNetworkReply::readyRead,this,[=]{//响应到达,读取所有的数据QByteArray s=rely->readAll();qDebug() << "服务器返回数据:" << QString(s);//将s数据转换为Json对象QJsonParseError err;QJsonDocument document=QJsonDocument::fromJson(s,&err);if(err.error!=QJsonParseError::NoError){qDebug()<<"QJson格式错误";return;}//将QJson字符串转换为QJson对象QJsonObject object1;object1=document.object();//获取状态码QString value1=object1["code"].toString();if(value1=="000"){//登录成功//0.获取token,将用户信息写入到logininstant中。//1.判断有没有记住密码,如果有记住密码,获取记住密码的状态//2.将账号和密码信息记录到配置文件中//3.显示登录成功页面(主页面)//获取tokenQString token=object1["token"].toString();qDebug()<<"token:"<<token;//获取token,将用户信息写入到logininstant中。saveLoginInfoData(account,token,ip,port);// QMessageBox::information(this,"登录成功","账号登录成功");//判断有没有记住密码bool checkBox=ui->rember_checkBox->isChecked();if(checkBox==false){//没有记住密码直接清除密码框ui->password_edit->clear();}//将账号密码保存到配置文件中m_common->writeLoginInfo(account,password,checkBox);//获取showMainWindow(account);}if(value1=="001"){QMessageBox::warning(this,"警告","登录");}});
}
//common.h文件:
//将用户信息 写入到配置文件
void writeLoginInfo(QString user, QString pwd, bool isRemeber, QString path=CONF_FILE);// 服务器信息写入到配置文件
void writeWebInfo(QString ip, QString port, QString path=CONF_FILE);相关接口(接口实现自行跳转项目链接去查看)
4.读取配置文件
- 当登录界面创建的时候,程序会先去读取conf.json文件内容.将账号和密码,服务器ip,端口号写入到登录界面中。
- 由于账号和密码在写入配置文件是加密的,读取账号和密码需要 先后进行 base64解密 和 desc解密,才显示到登录界面。
- desc加解密,需要在项目中添加des.c文件和des.h文件
//读取配置文件信息,将账号密码,服务器端口号写到界面中void Dialog::readConf(){QString user_base64=m_common->getConfValue("login","user");QString pwd_base64=m_common->getConfValue("login","pwd");QString remember=m_common->getConfValue("login","remember");//对账号进行base64解密和desc解密QByteArray usr_des=QByteArray::fromBase64(user_base64.toLocal8Bit());unsigned char usr[1024]={0};int usr_len;//进行desc解密if(DesDec((unsigned char*)usr_des.data(),usr_des.length(),usr,&usr_len)!=0){qDebug()<<"desc解密失败";}//账号解密成功,将账号显示到登录窗口QString s=QString::fromLocal8Bit((const char*)usr,usr_len);ui->account_edit->setText(s);if(remember=="yes"){ui->rember_checkBox->setCheckState(Qt::Checked);//记住密码,将密码显示到密码框上QByteArray pwd_des=QByteArray::fromBase64(pwd_base64.toLocal8Bit());unsigned char pwd[1024]={0};int pwd_len=0;//进行desc解密if(DesDec((unsigned char*)pwd_des.data(),pwd_des.length(),pwd,&pwd_len)!=0){qDebug()<<"密码解密失败";}//账号解密成功,将账号显示到登录窗口QString s1=QString::fromLocal8Bit((const char*)pwd,pwd_len);ui->password_edit->setText(s1);}//将ip地址和端口号显示到服务器设置页面QString ip=m_common->getConfValue("web_server","ip");QString port=m_common->getConfValue("web_server","port");ui->ip_edit->setText(ip);ui->port_eidt->setText(port);}
5.显示主界面
登录成功,显示主页面:
//创建主界面,并显示主界面
void Dialog::showMainWindow(QString account)
{//获取主页面mainwindow=MainWindow::getinstant();mainwindow->setUser(account);//将用户名显示到主页面上mainwindow->show();//显示主页面this->hide();//隐藏主页面connect(mainwindow,&MainWindow::switchUser,this,[=](){mainwindow->hide();this->show();});
}
相关文章:

【QT 网络云盘客户端】——登录界面功能的实现
目录 1.注册账号 2.服务器ip地址和端口号设置 3. 登录功能 4.读取配置文件 5.显示主界面 1.注册账号 1.点击注册页面,将数据 输入 到 用户名,昵称,密码,确认密码,手机,邮箱 的输入框中, 点…...

【复盘与分享】第十一届泰迪杯B题:产品订单的数据分析与需求预测
文章目录 题目第一问第二问2.1 数据预处理2.2 数据集分析2.2.1 训练集2.2.2 预测集 2.3 特征工程2.4 模型建立2.4.1 模型框架和评价指标2.4.2 模型建立2.4.3 误差分析和特征筛选2.4.4 新品模型 2.5 模型融合2.6 预测方法2.7 总结 结尾 距离比赛结束已经过去两个多月了。 整个过…...

X - Transformer
回顾 Transformer 的发展 Transformer 最初是作为机器翻译的序列到序列模型提出的,而后来的研究表明,基于 Transformer 的预训练模型(PTM) 在各项任务中都有最优的表现。因此,Transformer 已成为 NLP 领域的首选架构&…...

ubuntu下畅玩Seer(via wine)
第一步:安装wine 部分exe文件的运行需要32位的指令集架构,需要向Ubuntu系统中添加一个新的架构(i386),以支持32位的软件包。因为在64位的Ubuntu系统中,默认情况下只能安装和运行64位的软件。 通过添加i386…...

第五章:Spring下
第五章:Spring下 5.1:AOP 场景模拟 创建一个新的模块,spring_proxy_10,并引入下面的jar包。 <packaging>jar</packaging><dependencies><dependency><groupId>junit</groupId><artifactI…...
在CSDN学Golang云原生(Kubernetes基础)
一,k8s集群安装和升级 安装 Golang K8s 集群可以参照以下步骤: 准备环境:需要一组 Linux 服务器,并在每台服务器上安装 Docker 和 Kubernetes 工具。初始化集群:使用 kubeadm 工具初始化一个 Kubernetes 集群。例如&…...

给APK签名—两种方式(flutter android 安装包)
前提:给未签名的apk签名,可以先检查下apk有没有签名 通过命令行查看:打开终端或命令行界面,导入包含APK文件的目录,并执行以下命令: keytool -printcert -jarfile your_app.apk 将 your_app.apk替换为要检查…...

观察者模式、中介者模式和发布订阅模式
观察者模式 定义 观察者模式定义了对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都将得到通知,并自动更新 观察者模式属于行为型模式,行为型模式关注的是对象之间的通讯,观察者模式…...

PHP-Mysql图书管理系统--【白嫖项目】
强撸项目系列总目录在000集 PHP要怎么学–【思维导图知识范围】 文章目录 本系列校训本项目使用技术 首页phpStudy 设置导数据库后台的管理界面数据库表结构项目目录如图:代码部分:主页的head 配套资源作业: 本系列校训 用免费公开视频&am…...

网络传输层协议:UDP和TCP
背景知识 再谈端口号 端口号(Port)标识了一个主机上进行通信的不同的应用程序; 在TCP/IP协议中, 用 "源IP", "源端口号", "目的IP", "目的端口号", "协议号" 这样一个五元组来标识一个通信(可以通过 netstat -…...

ElementUI Select选择器如何根据value值显示对应的label
修改前效果如图所示,数据值状态应显示为可用,但实际上仅显示了状态码1,并没有显示其对应的状态信息。在排查了数据类型对应关系问题后,并没有产生实质性影响,只好对代码进行了如下修改。 修改前代码: <…...

Kotlin 内联函数语法之let、apply、also、run、with的用法与详解
一、介绍 kotlin的语法千奇百怪,今天我们将介绍项目中频率使用比较高的几个内联函数。 二、什么叫内联函数? 内联函数 的语义很简单:把函数体复制粘贴到函数调用处 。使用起来也毫无困难,用 inline关键字修饰函数即可。 语法&a…...
Swift 中如何判断是push 过来的页面 还是present过来的 页面
在 Swift 中,可以通过检查当前视图控制器的 presentingViewController 属性来判断是通过 push 过来的页面还是 present 过来的页面。 下面是一个示例代码,展示如何判断是通过 push 还是 present 过来的页面: if let presentingViewControll…...

基于K8s环境·使用ArgoCD部署Jenkins和静态Agent节点
今天是「DevOps云学堂」与你共同进步的第 47天 第⑦期DevOps实战训练营 7月15日已开营 实践环境升级基于K8s和ArgoCD 本文节选自第⑦期DevOps训练营 , 对于训练营的同学实践此文档依赖于基础环境配置文档, 运行K8s集群并配置NFS存储。实际上只要有个K8s集…...
874. 模拟行走机器人
874. 模拟行走机器人 机器人在一个无限大小的 XY 网格平面上行走,从点 (0, 0) 处开始出发,面向北方。该机器人可以接收以下三种类型的命令 commands : -2 :向左转 90 度-1 :向右转 90 度1 < x < 9 :…...

【Linux】- RPM 与 YUM
RPM 与 YUM 1.1 rpm 包的管理1.2 rpm 包的简单查询指令1.3 rpm 包的其它查询指令:1.4 卸载 rpm 包:2.1 安装 rpm 包3.1 yum3.2 yum 的基本指令3.3 安装指定的 yum 包3.4 yum 应用实例: 1.1 rpm 包的管理 介绍 rpm 用于互联网下载包的打包及安…...
Visual Studio 2015编译器 自动生成 XXX_EXPORTS宏
XXX_EXPORTS宏 XXX_EXPORTS宏是由Visual Studio 2015编译器自动生成的。这个宏用于标识当前项目是一个导出符号的动态链接库(DLL)项目。在使用Visual Studio 2015创建Win32项目时,编译器会自动添加这个宏到项目的预定义宏中。 这个宏的作用…...
HTML5的应用现状与发展前景
HTML5,作为Web技术的核心,已经深深地改变了我们看待和使用Web的方式。它不仅提供了数不尽的新特性和功能,还使得Web设计和开发更加互动、更加直观。这篇文章将探讨HTML5的当前应用现状,以及它的未来发展前景。 HTML5的应用现状 H…...

day44-Spring_AOP
0目录 1.2.3 1.Spring_AOP 实体类: Mapper接口: Service和实现类: 测试1: 运行后: 测试2:无此型号时 测试3:库存不足时 解决方案1:事务声明管理器 测试:…...
selenium IDE 接入jenkins-转载
Selenium-IDE脚本录制,selenium-side-runner自动化测试教程_51CTO博客_selenium ide录制脚本 备忘录...

idea大量爆红问题解决
问题描述 在学习和工作中,idea是程序员不可缺少的一个工具,但是突然在有些时候就会出现大量爆红的问题,发现无法跳转,无论是关机重启或者是替换root都无法解决 就是如上所展示的问题,但是程序依然可以启动。 问题解决…...

Lombok 的 @Data 注解失效,未生成 getter/setter 方法引发的HTTP 406 错误
HTTP 状态码 406 (Not Acceptable) 和 500 (Internal Server Error) 是两类完全不同的错误,它们的含义、原因和解决方法都有显著区别。以下是详细对比: 1. HTTP 406 (Not Acceptable) 含义: 客户端请求的内容类型与服务器支持的内容类型不匹…...

8k长序列建模,蛋白质语言模型Prot42仅利用目标蛋白序列即可生成高亲和力结合剂
蛋白质结合剂(如抗体、抑制肽)在疾病诊断、成像分析及靶向药物递送等关键场景中发挥着不可替代的作用。传统上,高特异性蛋白质结合剂的开发高度依赖噬菌体展示、定向进化等实验技术,但这类方法普遍面临资源消耗巨大、研发周期冗长…...

使用分级同态加密防御梯度泄漏
抽象 联邦学习 (FL) 支持跨分布式客户端进行协作模型训练,而无需共享原始数据,这使其成为在互联和自动驾驶汽车 (CAV) 等领域保护隐私的机器学习的一种很有前途的方法。然而,最近的研究表明&…...

深入理解JavaScript设计模式之单例模式
目录 什么是单例模式为什么需要单例模式常见应用场景包括 单例模式实现透明单例模式实现不透明单例模式用代理实现单例模式javaScript中的单例模式使用命名空间使用闭包封装私有变量 惰性单例通用的惰性单例 结语 什么是单例模式 单例模式(Singleton Pattern&#…...

【单片机期末】单片机系统设计
主要内容:系统状态机,系统时基,系统需求分析,系统构建,系统状态流图 一、题目要求 二、绘制系统状态流图 题目:根据上述描述绘制系统状态流图,注明状态转移条件及方向。 三、利用定时器产生时…...
Element Plus 表单(el-form)中关于正整数输入的校验规则
目录 1 单个正整数输入1.1 模板1.2 校验规则 2 两个正整数输入(联动)2.1 模板2.2 校验规则2.3 CSS 1 单个正整数输入 1.1 模板 <el-formref"formRef":model"formData":rules"formRules"label-width"150px"…...

微软PowerBI考试 PL300-在 Power BI 中清理、转换和加载数据
微软PowerBI考试 PL300-在 Power BI 中清理、转换和加载数据 Power Query 具有大量专门帮助您清理和准备数据以供分析的功能。 您将了解如何简化复杂模型、更改数据类型、重命名对象和透视数据。 您还将了解如何分析列,以便知晓哪些列包含有价值的数据,…...

sipsak:SIP瑞士军刀!全参数详细教程!Kali Linux教程!
简介 sipsak 是一个面向会话初始协议 (SIP) 应用程序开发人员和管理员的小型命令行工具。它可以用于对 SIP 应用程序和设备进行一些简单的测试。 sipsak 是一款 SIP 压力和诊断实用程序。它通过 sip-uri 向服务器发送 SIP 请求,并检查收到的响应。它以以下模式之一…...
Go 语言并发编程基础:无缓冲与有缓冲通道
在上一章节中,我们了解了 Channel 的基本用法。本章将重点分析 Go 中通道的两种类型 —— 无缓冲通道与有缓冲通道,它们在并发编程中各具特点和应用场景。 一、通道的基本分类 类型定义形式特点无缓冲通道make(chan T)发送和接收都必须准备好࿰…...