我用TCP发送文件,但是发送的时候界面就会卡死,求解决!

铭心客 发布于 2014/10/31 15:07
阅读 407
收藏 0
Qt
代码如下,这是书上的一个TCP发送文件的例子,但是没有解决界面卡死不动的问题。谁能 帮我看一下如果要用多线程应该怎么用?本人初学者,很多都不懂,最好帮我改一下代码谢谢各位大神 !!!
#include "widget.h"
#include "ui_widget.h"

Widget::Widget(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::Widget)
{
    ui->setupUi(this);

    loadSize = 4*1024;
    totalBytes = 0;
    bytesWrinten = 0;
    bytesToWrite = 0;
    tcpClient = new QTcpSocket(this);
    connect(tcpClient,SIGNAL(connected()),this,SLOT(startTransfer()) );
    //当连接成功时发送connected()信号,我们开始传文件
    connect(tcpClient,SIGNAL(bytesWritten(qint64)),this,SLOT(updataClientProgress(qint64)) );
    //当有数据发送时,就更新进度条
    connect(tcpClient,SIGNAL(error(QAbstractSocket::SocketError)),this
           ,SLOT(displayError(QAbstractSocket::SocketError)) );
    //当出错时,显示出错信息
    ui->sendButton->setEnabled(false);
    //开始使发送不可用
}

Widget::~Widget()
{
    delete ui;
}

void Widget::openFile()
{
    qDebug() << "openFile()" << endl;
    fileName = QFileDialog::getOpenFileName(this);
    if(!fileName.isEmpty())
    {
        ui->sendButton->setEnabled(true);
        ui->clientStatusLabel->setText(tr("打开文件%1成功").arg(fileName));
    }

}

void Widget::on_openButton_clicked()
{
    openFile();
}

void Widget::send()     //连接服务器
{
    qDebug() << "send()" << endl;
    ui->sendButton->setEnabled(false);
    bytesWrinten = 0;   //初始化已发送字节为0
    ui->clientStatusLabel->setText(tr("正在连接c..."));
    tcpClient->connectToHost(ui->hostLineEdit->text(),
                             ui->portLineEdit->text().toInt()); //连接

}

void Widget::startTransfer() //实现文件大小等信息的发送
{
    qDebug() << "startTransfer()" << endl;
    localFile = new QFile(fileName);
    if(!localFile->open(QFile::ReadOnly))
    {
        qDebug()<<"open file error!";
        return;
    }
    totalBytes = localFile->size();
    //文件总大小
    QDataStream sendOut(&outBlock,QIODevice::WriteOnly);
    sendOut.setVersion(QDataStream::Qt_5_3);
    QString currentFileName = fileName.right(fileName.size() -
                                fileName.lastIndexOf('/')-1);
    sendOut << qint64(0) << qint64(0) << currentFileName;
    //这里总大小是总大小信息、文件大小信息、文件名和实际文件大小的总和
    totalBytes += outBlock.size();
    sendOut.device()->seek(0);

    //返回outBolock的开始,用实际的大小信息代替两个qint64(0)空间
    sendOut<<totalBytes<<qint64((outBlock.size() - sizeof(qint64)*2));
    //发送完头数据后剩余数据的大小
    bytesToWrite = totalBytes - tcpClient->write(outBlock);
    ui->clientStatusLabel->setText(tr("已连接!"));
    outBlock.resize(0);
}

//更新进度条,实现文件的传送
void Widget::updataClientProgress(qint64 numBytes)
{
    qDebug() << "updataClientProgress()" << endl;
    bytesWrinten += (int)numBytes;
    //已经发送数据的大小
    if(bytesToWrite > 0) //如果已经发送了数据
    {
        outBlock = localFile->read(qMin(bytesToWrite,loadSize));
        //每次发送loadSize 大小的数据,这里设置为4KB,如果剩余的数据不足4KB
        //就发送剩余数据的大小
        bytesToWrite -= (int)tcpClient->write(outBlock);
        //发送完一次数据后还剩余数据的大小
        outBlock.resize(0);
        //清空发送缓冲区
    }
    else
    {
        localFile->close();//如果没有发送任何数据,则关闭文件

    }
    ui->clientprogressBar->setMaximum(totalBytes);
    ui->clientprogressBar->setValue(bytesWrinten);
    //更新进度条
    if(bytesWrinten == totalBytes) //发送完毕
    {
        ui->clientStatusLabel->setText(tr("发送文件 %1 成功!").arg(fileName));
        localFile->close();
        tcpClient->close();
    }
}

//显示错误
void Widget::displayError(QAbstractSocket::SocketError)
{
    qDebug() << "displayError()" << endl;
    qDebug() << tcpClient->errorString();
    tcpClient->close();
    ui->clientprogressBar->reset();
    ui->clientStatusLabel->setText(tr("Client Ready"));
    ui->sendButton->setEnabled(true);

}

void Widget::on_sendButton_clicked()
{
    qDebug() << "on_sendButton_clicked()" << endl;
    send();
}
加载中
0
千斤难买春秋醉
千斤难买春秋醉

就是把连接和传送文件从主线程移出去。。。

这样界面就不会卡

返回顶部
顶部