C++学习之网盘项目单例模式

目录

1.知识点概述

2.单例介绍

3.单例饿汉模式

4.饿汉模式四个版本

5.单例类的使用

6.关于token的作用和存储

7.样式表使用方法

8.qss文件中选择器介绍

9.qss文件样式讲解和测试

10.qss美化登录界面补充

11.QHTTPMULTIPART类的使用

12.文件上传协议

13.文件上传协议

14.QT中散列值的计算

15.设定nginx接受的最大文件上限


1.知识点概述

1.1 选择器类型
选择器
示例
说明
通用选择

*
匹配所有部件 匹配当前窗口所有的子窗口
类型选择

QWidget
匹配 QWidget 及其子类窗口的实例
类选择器
.QPushButton
匹配 QPushButton 的实例,但不包含子类。相当于 *

class\~="QPushButton"\] 。 ID 选择器 QPushButton#okButton 匹配所有 objectName 为 okButton 的 QPushButton 实例。 后代选择 器 QDialog QPushButton 匹配属于 QDialog 后代(孩子,孙子等)的 QPushButton 所有实 例。 子选择器 QDialog \>QPushButton 匹配属于 QDialog 直接子类的 QPushButton 所有实例。 **1.2 QSS** **的使用步骤** **1.3** **登录窗口设置** 1. 添加一个新文件 , 文件后缀 . qss - 位置 : 项目文件 xxx . pro 同一级 , 或者更深的目录中 - 添加注释 : 使用 /\*\*/ 2. qss 文件编码格式 , 必须是 utf - 8 3. 编写 qss 文件 , 给对应的控件设置样式 4. qss 加载到程序中 - 使用 QFile 将文件内容读到内存 , 得到了一个字符串 - 需要将这个字符串对应的样式设置给当前应用程序的对象 - QApplication 对象 - key 使用 qApp 全局指针进行访问 , 指向 QApplication 对象 - 设置方式 : setStyleSheet ( QString style ) 5. 将 qss 添加到资源文件中 ![](https://i-blog.csdnimg.cn/direct/b999e17c2cfe4617a3192bb840dd5754.png) ## 2.单例介绍 **2.1** **常用的四种方式** **application/x-www-form-urlencoded** **application/json** **text/xml** multipart/form-data /\* 登录窗口设置背景图片 \*/ /\* 登录窗口所有控件设置字体 , 字体大小 \*/ /\* 设置登录 / 注册 / 服务器设置窗口标题字体 , 字体大小 \*/ /\* 设置 logo 显示的图片 \*/ /\* 设置窗口标题字体 , 字体大小 , 加粗 \*/ /\* 没有账号马上注册按钮 : 字体颜色和添加下划线 \*/ /\* 登录 / 注册 /OK 按钮 : 字体颜色 , 宽度 , 高度 , 字体大小 , 显示图片 \*/ /\* 标题栏按钮 : normal, hover, press 三种状态切换 \*/ 1 2 3 4 5 6 7 8 # 请求行 POST http: //www.example.com HTTP/1.1 # 请求头 Content-Type: application/x-www-form-urlencoded;charset=utf-8 # 空行 # 请求数据 ( 向服务器提交的数据 ) title=test\&user=kevin\&passwd=32222 1 2 3 4 5 6 7 POST http://www.example.com HTTP/1.1 Content-Type: application/json;charset=utf-8 {"title": "test","sub":\[1,2,3\]} 1 2 3 POST http://www.example.com HTTP/1.1 Content-Type: text/xml \ \ \examples.getStateName\ \ \\41\\ \ \ 1 2 3 4 5 6 7 8 9 **2.2 multipart/form-data** 1. QHttpPart 类 2. QHttpMultiPart 类 **3.** **上传协议** 1. 秒传 客户端 POST http://www.example.com HTTP/1.1 Content-Type: multipart/form-data # 发送的数据 ------WebKitFormBoundaryPpL3BfPQ4cHShsBz \\r\\n Content-Disposition: form-data; name="file"; filename="qw.png"; md5="xxxxxxxxxx" Content-Type: image/png\\r\\n; \\r\\n ............. 文件内容 ................ ............. 文件内容 ................ ------WebKitFormBoundaryPpL3BfPQ4cHShsBz-- 1 2 3 4 5 6 7 8 9 10 // 设置头信息 void QHttpPart::setHeader ( QNetworkRequest::KnownHeaders header , const QVariant \& value ) // 设置数据 void QHttpPart::setBody ( const QByteArray \& body ) void QHttpPart::setBodyDevice ( QIODevice \* device ) 1 2 3 4 5 QHttpMultiPart::QHttpMultiPart ( ContentType contentType , QObject \* parent = Q_NULLPTR ) - 参数 contentType : QHttpMultiPart::FormDataType void QHttpMultiPart::append ( const QHttpPart \& httpPart ) - 参数 httpPart : 初始化好的数据块对象 QByteArray QHttpMultiPart::boundary () const - 返回值 : 数据格式中的分界线 // 自己指定分界线 , 一般情况下不需要 void QHttpMultiPart::setBoundary ( const QByteArray \& boundary ) ![](https://i-blog.csdnimg.cn/direct/72de0bd51727449cb20d7cccc97744ce.png) ## 3.单例饿汉模式 ![](https://i-blog.csdnimg.cn/direct/0298ecc4a3b342b6a5971cfad57bb4e7.png) ## 4.饿汉模式四个版本 ![](https://i-blog.csdnimg.cn/direct/ed23bf8033c44090b3dbdb44b17e7037.png) ![](https://i-blog.csdnimg.cn/direct/d0502ae0acba4215b6d403cd0205f5d1.png) ## 5.单例类的使用 ![](https://i-blog.csdnimg.cn/direct/87e306aaf2ec4e278c34ff564f88c617.png) ## 6.关于token的作用和存储 **上传协议** 1. 秒传 客户端 POST http://www.example.com HTTP/1.1 Content-Type: multipart/form-data # 发送的数据 ------WebKitFormBoundaryPpL3BfPQ4cHShsBz \\r\\n Content-Disposition: form-data; name="file"; filename="qw.png"; md5="xxxxxxxxxx" Content-Type: image/png\\r\\n; \\r\\n ............. 文件内容 ................ ............. 文件内容 ................ ------WebKitFormBoundaryPpL3BfPQ4cHShsBz-- 1 2 3 4 5 6 7 8 9 10 // 设置头信息 void QHttpPart::setHeader ( QNetworkRequest::KnownHeaders header , const QVariant \& value ) // 设置数据 void QHttpPart::setBody ( const QByteArray \& body ) void QHttpPart::setBodyDevice ( QIODevice \* device ) 1 2 3 4 5 QHttpMultiPart::QHttpMultiPart ( ContentType contentType , QObject \* parent = Q_NULLPTR ) - 参数 contentType : QHttpMultiPart::FormDataType void QHttpMultiPart::append ( const QHttpPart \& httpPart ) - 参数 httpPart : 初始化好的数据块对象 QByteArray QHttpMultiPart::boundary () const - 返回值 : 数据格式中的分界线 // 自己指定分界线 , 一般情况下不需要 void QHttpMultiPart::setBoundary ( const QByteArray \& boundary ) - 1 2 3 4 5 6 7 8 9 # url http: //127.0.0.1:80/md5 # post 数据格式 { user:xxxx, token:xxxx, md5:xxx, fileName: xxx } 1 2 3 4 5 6 7 8 9 **文件已存在** **(** **秒传成功** **)** **:** **{"code":"005"}** 秒传成功: {"code":"006"} 秒传失败: {"code":"007"} 服务器 2. 上传 客户端 **成功** **{"code":"008"}** 失败 {"code":"009"} 服务器 Nginx 设置 服务器端 fastCGI 部分 代码 # url http: //127.0.0.1:80/upload # post 数据格式 ------WebKitFormBoundary88asdgewtgewx\\r\\n Content-Disposition: form-data; user="mike"; filename="xxx.jpg"; md5="xxxx"; size=10240 Content-Type: text/plain 真正的文件内容 ------WebKitFormBoundary88asdgewtgewx-- 1 2 3 4 5 6 7 8 # 让 nginx 将数据转发给对应的 fastCGI 程序 location / upload { fastcgi_pass 地址 :port; include fastcig.conf; } # 重新加载 nginx 配置文件 sudo nginx -s reload // 取出 Content-Disposition 中的键值对的值 , 并得到文件内容 , 并将内容写入文件 int recv_save_file ( char \* user , char \* filename , char \* md5 , long \* p_size ) { int ret = 0 ; char \* file_buf = NULL ; char \* begin = NULL ; char \* p , \* q , \* k ; 8 char content_text \[ 512 \] = { 0 }; // 文件头部信息 char boundary \[ 512 \] = { 0 }; // 分界线信息 //==========\> 开辟存放文件的 内存 \<=========== file_buf = ( char \* ) malloc ( 4096 ); if ( file_buf == NULL ) { return - 1 ; } // 从标准输入 (web 服务器 ) 读取内容 int len = fread ( file_buf , 1 , 4096 , stdin ); if ( len == 0 ) { ret = - 1 ; free ( file_buf ); return ret ; } //===========\> 开始处理前端发送过来的 post 数据格式 \<============ begin = file_buf ; // 内存起点 p = begin ; /\* ------WebKitFormBoundary88asdgewtgewx\\r\\n Content-Disposition: form-data; user="mike"; filename="xxx.jpg"; md5="xxxx"; size=10240\\r\\n Content-Type: application/octet-stream\\r\\n ------WebKitFormBoundary88asdgewtgewx-- \*/ //get boundary 得到分界线 , ------WebKitFormBoundary88asdgewtgewx p = strstr ( begin , "\\r\\n" ); if ( p == NULL ) { ret = - 1 ; free ( file_buf ); return ret ; } // 拷贝分界线 strncpy ( boundary , begin , p - begin ); boundary \[ p - begin \] = '\\0' ; // 字符串结束符 p += 2 ; //\\r\\n // 已经处理了 p-begin 的长度 len -= ( p - begin ); //get content text head begin = p ; //Content-Disposition: form-data; user="mike"; filename="xxx.jpg"; md5="xxxx"; size=10240\\r\\n p = strstr ( begin , "\\r\\n" ); if ( p == NULL ) 59 { ret = - 1 ; free ( file_buf ); return ret ; } strncpy ( content_text , begin , p - begin ); content_text \[ p - begin \] = '\\0' ; p += 2 ; //\\r\\n len -= ( p - begin ); //======================================== 获取文件上传者 //Content-Disposition: form-data; user="mike"; filename="xxx.jpg"; md5="xxxx"; size=10240\\r\\n q = begin ; q = strstr ( begin , "user=" ); q += strlen ( "user=" ); q ++ ; // 跳过第一个 " k = strchr ( q , '"' ); strncpy ( user , q , k - q ); // 拷贝用户名 user \[ k - q \] = '\\0' ; //======================================== 获取文件名字 //"; filename="xxx.jpg"; md5="xxxx"; size=10240\\r\\n begin = k ; q = begin ; q = strstr ( begin , "filename=" ); q += strlen ( "filename=" ); q ++ ; // 跳过第一个 " k = strchr ( q , '"' ); strncpy ( filename , q , k - q ); // 拷贝文件名 filename \[ k - q \] = '\\0' ; //======================================== 获取文件 MD5 码 //"; md5="xxxx"; size=10240\\r\\n begin = k ; q = begin ; q = strstr ( begin , "md5=" ); q += strlen ( "md5=" ); q ++ ; // 跳过第一个 " k = strchr ( q , '"' ); strncpy ( md5 , q , k - q ); // 拷贝文件名 md5 \[ k - q \] = '\\0' ; //======================================== 获取文件大小 //"; size=10240\\r\\n begin = k ; q = begin ; q = strstr ( begin , "size=" ); q += strlen ( "size=" ); k = strstr ( q , "\\r\\n" ); char tmp \[ 256 \] = { 0 }; strncpy ( tmp , q , k - q ); // 内容 111 使用 fastCGI 管理器启动 fastCGI 程序 **4. Http** **上传下载进度** tmp \[ k - q \] = '\\0' ; \* p_size = strtol ( tmp , NULL , 10 ); // 字符串转 long begin = p ; p = strstr ( begin , "\\r\\n" ); p += 2 ; //\\r\\n len -= ( p - begin ); // 下面才是文件的真正内容 /\* ------WebKitFormBoundary88asdgewtgewx\\r\\n Content-Disposition: form-data; user="mike"; filename="xxx.jpg"; md5="xxxx"; size=10240\\r\\n Content-Type: application/octet-stream\\r\\n 真正的文件内容 \\r\\n ------WebKitFormBoundary88asdgewtgewx-- \*/ // begin 指向正文首地址 begin = p ; // 将文件内容抠出来 // 文件内容写如本地磁盘文件 free ( file_buf ); return ret ; } spawn-fcgi -a IP 地址 -p 端口 -f ./fastcgi 程序 - 提示启动失败 - ldd fastCGI 程序 ![](https://i-blog.csdnimg.cn/direct/7f131646df8d40e0825bb2e0b8344063.png) ![](https://i-blog.csdnimg.cn/direct/a6c1bf2143d7417eaa41044652a21a0b.png) ## 7.样式表使用方法 ## 8.qss文件中选择器介绍 ## 9.qss文件样式讲解和测试 ## 10.qss美化登录界面补充 ## 11.QHTTPMULTIPART类的使用 ## 12.文件上传协议 ## 13.文件上传协议 ## 14.QT中散列值的计算 ## 15.设定nginx接受的最大文件上限

相关推荐
风尚云网7 分钟前
风尚云网|前端|JavaScript性能优化实战:从瓶颈定位到高效执行
前端·javascript·学习·html
打不了嗝 ᥬ᭄21 分钟前
红黑树的模拟实现
c++
猪猪虾的业余生活31 分钟前
QT实现WPS功能
开发语言·qt·wps
曦月逸霜32 分钟前
第十六次CCF-CSP认证(含C++源码)
数据结构·c++·算法·ccf-csp
PfCoder33 分钟前
C# 反射(Reflection)详解
开发语言·c#·visual studio
Antonio91540 分钟前
【设计模式】单件模式
开发语言
ue星空1 小时前
UE5猴子神庙教程学习笔记
笔记·学习·ue5
tutgxuzyj1 小时前
语言合成模型Spark-TTS-0.5B学习笔记
笔记·学习·spark
-SGlow-1 小时前
Linux网络相关概念和重要知识(2)(UDP套接字编程、聊天室的实现、观察者模式)
linux·运维·服务器·网络·c++·观察者模式·udp
闲人编程1 小时前
OpenCV图像读写与Mat对象深度解析
c++·python·opencv