最近做微信开发,需要上传素材到微信服务器,我就用qt写了一个界面上传素材,首先我们来看下最终的界面:
然后将里面的access_token后面的lineEdit命名为:accessMediaEdit,type后面的ComboBox命名为typeComboBox,filePath后面的lineEdit命名为:fileMediaEdit,浏览按钮命名为fileMediaBtn,result后面TextEdit命名为:mediaTextEdit,upload按钮命名为:uploadMediaBtn,好了,现在上传临时多媒体文件这一模块的界面已经弄好了,接下来看代码实现,
upload按钮连接的槽:
void Widget::on_uploadMedia_slot() {
QString url = MEDIA_URL;
QString type = ui->typeComboBox->currentText();
url.replace(QRegularExpression("ACCESS_TOKEN"), QString(ui->accessMediaEdit->text())).replace(QRegularExpression("TYPE"), type);
AppUtil::getInstance()->httpRequest(url, NULL, ui->fileMediaEdit->text(), "media");
}
这上面是upload按钮所触发的槽,接下来我一个解释,前面几行是获数据,然后有一行代码:
url.replace(QRegularExpression(“ACCESS_TOKEN”), QString(ui->accessMediaEdit->text())).replace(QRegularExpression(“TYPE”), type);
这一行代码是上传临时多媒体的api,它的地址为:
#define MEDIA_URL "http://file.api.weixin.qq.com/cgi-bin/media/upload?access_token=ACCESS_TOKEN&type=TYPE"
然后我们来看看AppUtil::getInstance()->httpRequest(url, NULL, ui->fileMediaEdit->text(), “media”);这个方法的定义:
void AppUtil::httpRequest(QString url, QString type, QString filePath, QString flag)
{
qDebug() << "httpRequest---strat";
if( !mNetManager ) {
mNetManager = new QNetworkAccessManager(this);
}
this->flag = flag;
QFile file(filePath);
if(file.exists()) {
if( !file.open(QIODevice::ReadOnly)) {
QMessageBox::warning(NULL, QObject::tr("warning"), QObject::tr("打开传输的文件失败"), QMessageBox::Yes);
return;
}
}
//读取所有文件
QByteArray fileContent = file.readAll();
//边界的时候这里加两杠
QString boundary = "----weasdashDsdesd";
//起始边界
QString startBoundary = "--" + boundary;
//结束边界
QString endBoundary = "\r\n--" + boundary + "--\r\n";
//设置传输类型
QString qContentType = "multipart/form-data; boundary=" + boundary;
//要发送的内容
QByteArray content;
QString tempStr = startBoundary;
tempStr += "\r\nContent-Disposition: form-data; name=\"media\"; filename=\""+getExt(file)+"\"\r\n";
tempStr += "Content-Type: " + getType(file) + "\r\n\r\n";
content.append(tempStr.toLatin1());
content.append(fileContent);
content.append(endBoundary);
//构造http请求
QNetworkRequest req;
QSslConfiguration config;
config.setPeerVerifyMode(QSslSocket::VerifyNone);
config.setProtocol(QSsl::TlsV1SslV3);
req.setSslConfiguration(config);
req.setUrl(QUrl(url));
req.setHeader(QNetworkRequest::ContentTypeHeader, qContentType.toLatin1());
QNetworkReply * reply = mNetManager->post(req, content);
connect(mNetManager, SIGNAL(finished(QNetworkReply *)), this, SLOT(on_seccess_slot(QNetworkReply *)));
}
这个方法是模拟multipart/form-data格式的表单上传数据,我们来看看这种数据的格式是怎样的:
http协议请求头
http协议请求体
看到上面的两张图,就是我们需要模仿的内容。
QSslConfiguration config;
config.setPeerVerifyMode(QSslSocket::VerifyNone);
config.setProtocol(QSsl::TlsV1SslV3);
这三行代码是设置该请求能够发动https请求,然而,qt本身并不带https请求,如果需要让qt支持https请求,需要自己另外下载东西,我就不赘述了,具体的可以参考这篇博客QSslSocket解决办法需要注意的是,你下载的库一定要要对应你安装的Qt creator版本,而不是对应你的操作系统版本,例如你的操作系统是64位,但是你的qt creator安装的却是32位,那么你安装的应该是32位而不是64位。
req.setSslConfiguration(config);
req.setUrl(QUrl(url));
req.setHeader(QNetworkRequest::ContentTypeHeader, qContentType.toLatin1());
QNetworkReply * reply = mNetManager->post(req, content);
这几行代码就不用多说了,只是正常的发动post请求,最后这一行
connect(mNetManager, SIGNAL(finished(QNetworkReply )), this, SLOT(on_seccess_slot(QNetworkReply )));这是连接信号与槽,
一旦服务器将所有的信息都发送回来,那么QNetworkAccessManager就会发射一个finished(QNetworkReply *)信号,然后我们就可以通过这个信号读取服务器的响应了。这个是qt上传临时多媒体的过程,至于这里面的其他功能比较类似,我就不去赘述了,只要理解我这里介绍的内容,其他的功能照样可以自己写出来。
源码下载:点我下载