目录
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 添加到资源文件中

## 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 )

## 3.单例饿汉模式

## 4.饿汉模式四个版本


## 5.单例类的使用

## 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 程序


## 7.样式表使用方法
## 8.qss文件中选择器介绍
## 9.qss文件样式讲解和测试
## 10.qss美化登录界面补充
## 11.QHTTPMULTIPART类的使用
## 12.文件上传协议
## 13.文件上传协议
## 14.QT中散列值的计算
## 15.设定nginx接受的最大文件上限