一段来源于《精通Qt编程》的文件传输功能的代码

这篇博客分享了一段从《精通Qt编程》中学习并实践的文件传输功能代码。作者将服务器端和客户端设计为继承自QDialog,并在原有基础上添加了界面元素和上传文件功能。虽然代码主要基于书中的示例,但作者表示对某些部分的理解仍需加深,以此鼓励读者一同学习和探讨。
摘要由CSDN通过智能技术生成

服务器端和客户端都是继承于QDialog,写个主程序让他们显示即可。

代码来源于《精通Qt编程》,我觉得就是把这本书背下来,离精通还很远。代码是3个月前我自己照着pdf的书敲出来的。自己添加了一些界面代码,和一些投文件。核心代码未作修改。

有些地方我现在还没搞的很清楚,再回顾回顾学习学习。


fileTransDialog.h

#ifndef FILETRANSDIALOG_H
#define FILETRANSDIALOG_H
 
 
#include <QDialog>
#include <QtNetwork/QAbstractSocket>
#include <QPushButton>
#include <QProgressBar>
#include <QLabel>
#include <QtNetwork/QTcpSocket>
#include <QtNetwork/QHostAddress>
#include <QtGui/QDialogButtonBox>
#include <QFile>
#include <QString>
#include <QByteArray>
#include <QFileDialog>
#include <QApplication>
#include <QMessageBox>
#include <QDebug>
#include <QHBoxLayout>
#include <QVBoxLayout>
 
class fileTransDialog : public QDialog
{
    Q_OBJECT
public:
    QString strip;
    fileTransDialog(QString strIP);
 
public slots:
    void start();
    void startTransfer();
    void updateClientProgress(qint64 numBytes);
    void displayError(QAbstractSocket::SocketError socketError);
    void openFile();
 
private:
    QProgressBar *clientProgressBar;
    QLabel *clientStatusLabel;
    QPushButton *startButton;
    QPushButton *quitButton;
    QPushButton *openButton;
    QDialogButtonBox *buttonBox;
    QTcpSocket tcpClient;
 
    QHBoxLayout *hLayout;
    QVBoxLayout *vLayout;
 
    qint64 TotalBytes;
    qint64 bytesWritten;
    qint64 bytesToWrite;
    qint64 loadSize;
    QString fileName;
    QFile *localFile;
    QByteArray outBlock;
 
};
 
 
 
#endif // FILETRANSDIALOG_H


fileTransDialog.cpp

#include <fileTransDialog.h>

#include <QtGlobal>



fileTransDialog::fileTransDialog(QString strIP)

{

    loadSize = 4*1024;

    TotalBytes = 0;

    bytesWritten = 0;

    bytesToWrite = 0;

    clientProgressBar = new QProgressBar;

    clientStatusLabel = new QLabel(tr("Client has been ready"));

    startButton = new QPushButton(tr("Start"));

    quitButton = new QPushButton(tr("Quit"));

    openButton = new QPushButton(tr("Open"));

    startButton->setEnabled(false);



    vLayout = new QVBoxLayout;

    vLayout->addWidget(clientProgressBar);

    vLayout->addWidget(clientStatusLabel);

    buttonBox = new QDialogButtonBox(Qt::Horizontal);

    buttonBox->addButton(startButton,QDialogButtonBox::ActionRole);

    buttonBox->addButton(openButton,QDialogButtonBox::ActionRole);

    buttonBox->addButton(quitButton,QDialogButtonBox::ActionRole);

    hLayout = new QHBoxLayout;

    hLayout->addLayout(vLayout);

    vLayout->addWidget(buttonBox);

    setLayout(hLayout);



    connect(startButton,SIGNAL(clicked()),this,SLOT(start()));

    connect(quitButton,SIGNAL(clicked()),this,SLOT(close()));

    connect(openButton,SIGNAL(clicked()),this,SLOT(openFile()));

    connect(&tcpClient,SIGNAL(connected()),

            this,SLOT(startTransfer()));

    connect(&tcpClient,SIGNAL(bytesWritten(qint64)),

            this,SLOT(updateClientProgress(qint64)));

    connect(&tcpClient,SIGNAL(error(QAbstractSocket::SocketError)),

            this,SLOT(displayError(QAbstractSocket::SocketError)));

    this->strip = strIP;

    qDebug()<<this->strip;

}





void fileTransDialog::openFile()

{

    fileName = QFileDialog::getOpenFileName(this);

    if (!fileName.isEmpty())

        startButton->setEnabled(true);

}



void fileTransDialog::start()

{

    startButton->setEnabled(false);

    //QApplication::setOverrideCursor(Qt::WaitCursor);

    bytesWritten = 0;

    clientStatusLabel->setText(tr("connecting..."));

    tcpClient.connectToHost(QHostAddress(this->strip),16689);

}



void fileTransDialog::startTransfer()

{

    localFile = new QFile(fileName);

    if(!localFile->open(QFile::ReadOnly))

    {

        QMessageBox::warning(this,tr("Application"),

                             tr("can not open %1:\n%2.")

                             .arg(fileName)

                             .arg(localFile->errorString()));

        return;

    }

    TotalBytes = localFile->size();



    QDataStream sendOut(&outBlock,QIODevice::WriteOnly);

    sendOut.setVersion(QDataStream::Qt_4_7);



    QString currentFile = fileName.right(fileName.size()-

                                         fileName.lastIndexOf('/')-1);

    sendOut<<qint64(0)<<qint64(0)<<currentFile;

    TotalBytes += outBlock.size();

    sendOut.device()->seek(0);

    sendOut<<TotalBytes<<qint64(outBlock.size()- sizeof(qint64)*2);

    bytesToWrite = TotalBytes - tcpClient.write(outBlock);

    clientStatusLabel->setText(tr("Connected!"));

    qDebug()<<currentFile<<TotalBytes;

    outBlock.resize(0);

}



void fileTransDialog::updateClientProgress(qint64 numBytes)

{

    bytesWritten += (int)numBytes;

    if(bytesToWrite > 0)

    {

        if(bytesToWrite > 0)

        {

            outBlock = localFile->read(qMin(bytesToWrite,loadSize));

            bytesToWrite -= (int)tcpClient.write(outBlock);

            outBlock.resize(0);

        }

        else

        {

            localFile->close();

        }

    }

    clientProgressBar->setMaximum(TotalBytes);

    clientProgressBar->setValue(bytesWritten);

    clientStatusLabel->setText(tr("Have send %1MB").arg(bytesWritten/(1024*1024)));

}



void fileTransDialog::displayError(QAbstractSocket::SocketError socketError)

{

    if(socketError == QTcpSocket::RemoteHostClosedError)

        return;

    QMessageBox::warning(this,tr("NetWork"),

                             tr("generate the following error:%1.")

                             .arg(tcpClient.errorString()));

    tcpClient.close();

    clientProgressBar->reset();

    clientStatusLabel->setText(tr("Client has been ready"));

    startButton->setEnabled(true);

    QApplication::restoreOverrideCursor();

}


fileTransDialogS.h

#ifndef FILETRANSDIALOGS_H

#define FILETRANSDIALOGS_H



#include <QDialog>

#include <QPushButton>

#include <QLabel>

#include <QProgressBar>

#include <QDialogButtonBox>

#include <QMessageBox>

#include <QtNetwork/QAbstractSocket>

#include <QtNetwork/QTcpServer>

#include <QtNetwork/QTcpSocket>

#include <QtNetwork/QHostAddress>

#include <QFile>

#include <QApplication>

#include <QDebug>

#include <QObject>

#include <QHBoxLayout>

#include <QVBoxLayout>

#include <QDataStream>



class fileTransDialogS : public QDialog

{

    Q_OBJECT



public:

    fileTransDialogS(QWidget *parent = 0);



private slots:

    void start();

    void acceptConnection();

    void updateServerProgress();

    void displayError(QAbstractSocket::SocketError socketError);



private:

    QProgressBar *clientProgressBar;

    QProgressBar *serverProgressBar;

    QLabel *serverStatusLabel;

    QPushButton *startButton;

    QPushButton *quitButton;



    QDialogButtonBox *buttonBox;

    QVBoxLayout *vLay;

    QHBoxLayout *hLay;

    QTcpServer tcpServer;

    QTcpSocket *tcpServerConnection;

    qint64 TotalBytes;

    qint64 bytesReceived;

    qint64 fileNameSize;

    QString fileName;

    QFile *localFile;

    QByteArray inBlock;

};





#endif // FILETRANSDIALOGS_H




fileTransDialogS.cpp


#include <fileTransDialogS.h>

#include <QString>



fileTransDialogS::fileTransDialogS(QWidget *parent)

    :QDialog(parent)

{

    TotalBytes = 0;

    bytesReceived = 0;

    fileNameSize = 0;

    serverProgressBar = new QProgressBar;

    serverStatusLabel = new QLabel(tr("Server has been ready"));

    startButton = new QPushButton(tr("Receive"));

    quitButton = new QPushButton(tr("Quit"));



    buttonBox = new QDialogButtonBox;

    buttonBox->addButton(startButton,QDialogButtonBox::ActionRole);

    buttonBox->addButton(quitButton,QDialogButtonBox::ActionRole);



    vLay = new QVBoxLayout;

    vLay->addWidget(serverProgressBar);

    vLay->addWidget(serverStatusLabel);

    //vLay->addLayout();

    hLay = new QHBoxLayout;

    hLay->addWidget(buttonBox);

    hLay->addLayout(vLay);



    setLayout(hLay);



    //..............



    connect(startButton,SIGNAL(clicked()),this,SLOT(start()));

    connect(quitButton,SIGNAL(clicked()),this,SLOT(close()));

    connect(&tcpServer,SIGNAL(newConnection()),this,SLOT(acceptConnection()));



}



void fileTransDialogS::start()

{

    startButton->setEnabled(false);



    //QApplication::setOverrideCursor(Qt::WaitCursor);

    bytesReceived = 0;



    while(!tcpServer.isListening()&&

          !tcpServer.listen(QHostAddress::LocalHost,16689))

    {

        QMessageBox::StandardButton ret = QMessageBox::critical(this,

                                                                tr("circle"),

                                                                tr("can not test: %1")

                                                                .arg(tcpServer.errorString()),

                                                                QMessageBox::Retry|

                                                                QMessageBox::Cancel);

        if(ret == QMessageBox::Cancel)

            return;

    }

    serverStatusLabel->setText(tr("Listening..."));

}



void fileTransDialogS::acceptConnection()

{

    tcpServerConnection = tcpServer.nextPendingConnection();

    connect(tcpServerConnection,SIGNAL(readyRead()),

            this,SLOT(updateServerProgress()));

    connect(tcpServerConnection,SIGNAL(error(QAbstractSocket::SocketError)),

            this,SLOT(displayError(QAbstractSocket::SocketError)));

    serverStatusLabel->setText(tr("accepted connection"));

    tcpServer.close();

}



void fileTransDialogS::displayError(QAbstractSocket::SocketError socketError)

{

    if(socketError == QTcpSocket::RemoteHostClosedError)

        return;

    QMessageBox::information(this,tr("NetWork"),

                             tr("generate the following error:%1.")

                             .arg(tcpServer.errorString()));

}



void fileTransDialogS::updateServerProgress()

{

    QDataStream in(tcpServerConnection);

    in.setVersion(QDataStream::Qt_4_7);

    if(bytesReceived <= sizeof(qint64)*2)

    {



        if((tcpServerConnection->bytesAvailable() >=

           sizeof(qint64)*2)&&(fileNameSize==0))

        {



            in>>TotalBytes>>fileNameSize;

            bytesReceived += sizeof(qint64)*2;

        }

        if((tcpServerConnection->bytesAvailable()>=

            fileNameSize)&&(fileName ==0))

        {

            in>>fileName;

            bytesReceived += fileNameSize;

            localFile = new QFile(fileName);

            if(!localFile->open(QFile::WriteOnly))

            {

                QMessageBox::warning(this,tr("Application"),

                                     tr("can not read file %1:\n%2.")

                                     .arg(fileName)

                                     .arg(localFile->errorString()));

                return;

            }

        }

        else

        {

           return;

        }

    }

    if(bytesReceived<TotalBytes)

    {

        bytesReceived += tcpServerConnection->bytesAvailable();

        inBlock = tcpServerConnection->readAll();

        localFile->write(inBlock);

        inBlock.resize(0);

    }

    serverProgressBar->setMaximum(TotalBytes);

    serverProgressBar->setValue(bytesReceived);

    qDebug()<<bytesReceived;

    serverStatusLabel->setText(tr("Received %1MB")

                               .arg(bytesReceived /(1024*1024)));

    if(bytesReceived == TotalBytes)

    {



        tcpServerConnection->close();

        startButton->setEnabled(true);

        startButton->setText("Complete!");

        QApplication::restoreOverrideCursor();

    }



}











评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值