QT進行檔案上傳 (類似於百度雲網盤)
阿新 • • 發佈:2019-01-09
分為伺服器和客戶端
下面來具體貼出程式碼。 每一句的具體註釋都在,幫助理解:
先貼 客戶端
首先在專案檔案 .pro中新增 network
widget.h
#ifndef WIDGET_H #define WIDGET_H #include <QWidget> #include <QtcpSocket> #include<QFileDialog> #include<QFileInfo> #include<QTimer> #include<QFile> namespace Ui { class Widget; } class Widget : public QWidget { Q_OBJECT public: explicit Widget(QWidget *parent = 0); ~Widget(); private slots: void on_connectBtn_clicked(); void connectedSlot(); void on_openBtn_clicked(); void on_uploadBtn_clicked(); void sendFileSlot(); private: Ui::Widget *ui; QTcpSocket *socket; QString filePath; QString fileName; int fileSize; QTimer timer; }; #endif // WIDGET_H
main.cpp
#include "widget.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
Widget w;
w.show();
return a.exec();
}
widget.cpp
#include "widget.h" #include "ui_widget.h" Widget::Widget(QWidget *parent) : QWidget(parent), ui(new Ui::Widget) { ui->setupUi(this); setWindowTitle("客戶端"); socket = new QTcpSocket(this); connect(socket,SIGNAL(connected()),this,SLOT(connectedSlot())); } Widget::~Widget() { delete ui; } void Widget::connectedSlot() { ui->connectBtn->setEnabled(false); } void Widget::on_connectBtn_clicked() { socket->connectToHost("192.168.0.111",8888); } //開啟檔案按鈕的槽函式 作用是得到檔案,並顯示檔案資訊 void Widget::on_openBtn_clicked() { //獲得檔案路徑,並且判斷是否為空 filePath = QFileDialog::getOpenFileName(this,"open","./","ALL(*.*)"); if(filePath.isEmpty()) { return; } //接下來得到檔案資訊,使用QFileInfo QFileInfo info(filePath); fileName = info.fileName(); fileSize = info.size(); ui->textBrowser->append("要上傳的檔案為:"+fileName); } //傳送檔案 按鈕的槽函式的功能是 傳送檔名和檔案大小。 void Widget::on_uploadBtn_clicked() { // 我們可以 先發送 檔名和檔案大小,然後定時器停頓幾秒, //然後開始傳送檔案,這樣的話可以有效的吧檔案區分開來, //可以 做一個timeout 訊號 來開始傳送檔案,完美。 QString headInfo = fileName+ "##" +QString::number(fileSize); QByteArray arr; arr.append(headInfo); //因為下面的引數型別是 QByteArray 所以在上面需要定義一個arr; socket->write(arr); timer.start(100); //接下來連線timeout 訊號和槽函式 connect(&timer,SIGNAL(timeout()),this,SLOT(sendFileSlot())); } // 接下來來實現 傳送檔案的 槽函式 //接收到 timeout訊號以後 開始傳送檔案 void Widget::sendFileSlot() { timer.stop(); //開始傳送檔案內容 QFile file(filePath); bool ok = file.open(QIODevice::ReadOnly); if(true == ok) { QByteArray arr = file.readAll(); qint64 ret = socket->write(arr); if( fileSize==ret) { ui->textBrowser->append("檔案上傳成功!"); file.close(); } } }
UI介面如下:
下面貼伺服器端的 程式碼
1.也是先新增network
widget.h
#ifndef WIDGET_H #define WIDGET_H #include <QWidget> #include<QTcpServer> #include<QTcpSocket> #include<QFile> #include <QHostAddress> #include<QDebug> namespace Ui { class Widget; } class Widget : public QWidget { Q_OBJECT public: explicit Widget(QWidget *parent = 0); ~Widget(); private slots: void connectedSlot(); void recvSlot(); private: Ui::Widget *ui; QTcpServer *server; QTcpSocket *socket; QString fileName; int fileSize; bool flag; }; #endif // WIDGET_H
main.cpp
#include "widget.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
Widget w;
w.show();
return a.exec();
}
widget.cpp
#include "widget.h"
#include "ui_widget.h"
Widget::Widget(QWidget *parent) :
QWidget(parent),
ui(new Ui::Widget)
{
ui->setupUi(this);
setWindowTitle("接收端");
server = new QTcpServer(this);
//伺服器一開啟就進行監聽查詢,
server->listen(QHostAddress("192.168.0.111"),8888);
flag = true;
connect(server,SIGNAL(newConnection()),this,SLOT(connectedSlot()));
}
Widget::~Widget()
{
delete ui;
}
void Widget::connectedSlot()
{
socket = server->nextPendingConnection();
if(NULL == socket)
{
return ;
}
connect(socket,SIGNAL(readyRead()),this,SLOT(recvSlot()));
}
void Widget::recvSlot()
{
QByteArray arr = socket->readAll();
if(true == flag)
{
qDebug()<<QString(arr);
QString str = QString(arr);
fileName = str.section("##",0,0);
fileSize = str.section("##",1,1).toInt();
ui->textBrowser->setText("要接收的檔案資訊為:"+fileName+QString::number(fileSize));
flag = false;
}
else
{
//這是後面上傳檔案以後需要儲存的絕對路徑
QFile file("F:\\"+fileName);
bool ok = file.open(QIODevice::WriteOnly);
qint64 size = 0;
if(true == ok)
{
qint64 ret = file.write(arr);
size += ret ;
if(size ==fileSize)
{
ui->textBrowser->append("檔案接受完成!");
flag = true;
file.close();
}
}
}
}
ui 介面如下