این پست یک مثال از تبادل اطلاعات با وب هست.
یک کاربرد جالب و مهم که بعضی وقتا بهش نیاز داریم آپلود کردن یک فایل از روی رایانه به سایت مورد نظر هست.
چون مثالی برای آپلود فایل در رفرنس کیوت نیامده و نمونه کدهایی هم که در اینترنت پیدا کردم با استفاده از کلاس QHttp بود من این مثال رو برای استفاده از QNetworkAccessManager تطبیق دادم.
QNetworkAccessManager کلاسی با رابط سطح بالاتری هست که شما باید در اغلب برنامه هاتون استفاده کنید؛ مگر اینکه نیاز به ارتباط سطح پایینتری برای تبادل اطلاعات با وب داشته باشید که در چنان صورتی از کلاسهای دیگه مثل QHttp استفاده میکنید.
این برنامه یک فایل با نام test.txt رو که در دایرکتوری جاری قرار داره به سرور آپلود میکنه.
البته محدودیتی وجود نداره که فایل ما فقط از نوع متنی باشه؛ هر نوع فایل دیگری میتونه باشه.
فایلهای کد برنامه:
فایل main.cpp:
#include <QApplication>
#include "uploader.h"
int main(int argc, char *argv[])
{
QApplication app(argc, argv);
Uploader u;
return app.exec();
}
فایل uploader.h:
#include <QFile>
#include <QObject>
#include <QNetworkAccessManager>
#include <QUrl>
#include <QNetworkRequest>
#include <qdebug.h>
#include <QNetworkReply>
#include <QBuffer>
#include <QApplication>
class Uploader : public QObject
{
Q_OBJECT
public:
Uploader() {
uploadManager = new QNetworkAccessManager(this);
connect(uploadManager, SIGNAL(finished(QNetworkReply*)),
this, SLOT(uploadFinished(QNetworkReply*)));
postData=new QByteArray;
buffer=new QBuffer(postData, this);
QFile *file=new QFile("test.txt");
file->open(QIODevice::ReadOnly);
boundary = "----xmdjekop098356td----";
(*postData)=QString("--" + boundary + "\r\n").toAscii();
(*postData) += "Content-Disposition: form-data; name=\"test\"; filename=\"test.txt\"\r\n";
(*postData) += "Content-Type: text/plain\r\n\r\n";
(*postData) += file->readAll();
(*postData) += "\r\n";
(*postData) += QString("--" + boundary + "--\r\n").toAscii();
buffer->open(QBuffer::ReadOnly);
QNetworkRequest req(QUrl("http://localhost/upload.php"));
req.setHeader(QNetworkRequest::ContentTypeHeader, "multipart/form-data; boundary="+boundary);
qDebug()<<"uploading result...";
uploadManager->post(req, buffer);
}
public slots:
void uploadFinished(QNetworkReply* r) {
if(r->error()) {
qDebug()<<"Upload network error: "<<r->error();
r->deleteLater();
qApp->exit(1);
return;
}
qDebug()<<"upload reply: "<<r->readAll();
r->deleteLater();
qApp->exit(0);
}
private:
QNetworkAccessManager* uploadManager;
QBuffer* buffer;
QByteArray* postData;
QString boundary;
};
محتویات فایل پروژه:
TEMPLATE = app
TARGET =
DEPENDPATH += .
INCLUDEPATH += .
# Input
HEADERS += uploader.h
SOURCES += main.cpp
QT+=network
CONFIG+=console
همونطور که میبینید در دو خط آخر فایل پروژه قابلیت شبکه و خروجی خط فرمان رو به برنامه اضافه کردیم.
اضافه کردن QT+=network برای بکار بردن ماجول شبکهء کیوت هست که در برنامه هایی که ارتباط شبکه ای دارن اضافه کردن این فرمان به فایل پروژه ضروری است و نیاز دارید تا بصورت دستی اضافه کنید (مگر اینکه از محیط گرافیکی طراحی کیوت برای تعریف پروژه استفاده کرده باشید و در اونجا مشخص کرده باشید که برنامهء کارکرد شبکه ای داره).
اضافه کردن امکان خروجی خط فرمان هم در اینجا صرفا بخاطر این هست که با خروجیهای چاپ شده توسط برنامه متوجه بشیم برنامه چکار میکنه و عملیات با موفقیت انجام شده یا خیر. مشخصه که معمولا برای برنامه در مراحل آزمایش یا مثالها، بعلت صرفه جویی زیاد در وقت و انرژی برنامه نویس، از رابط خط فرمان برای خروجی و گزارش وضعیت برنامه استفاده میکنیم.
اینهم نمونهء بسیار ساده شده ای از برنامهء سمت سرور ما که فایل آپلود شده رو دریافت و ذخیره میکنه.
شما برای تست برنامهء آپلودر کیوت به چنین اسکریپت یا برنامهء دیگری هم در سمت سرور نیاز دارید.
نام فایل upload.php هست که در دایرکتوری ریشهء localhost ذخیره میکنیم:
<?php
if (move_uploaded_file($_FILES['test']['tmp_name'], 'test.txt')) echo 'uploaded successfully.';
else echo 'upload failed!';
?>