QT定时器实现文件交互式下载,收一个包,发下一个

通过子线程接收数据,发送到每个页面之后,接收函数解析数据,定时器根据解析结果下发。

当前未加入校验代码,可正常运行。

主要函数如下:

/**
 * @brief UpdateWidget::onBrowserBtnClicked
 */
void UpdateWidget::onBrowserBtnClicked()
{
    qDebug() << "onBrowserBtnClicked";
    QFileDialog dlg;
    QStringList filters;

    //获取用户选择文件,显示路径
    fileName = QFileDialog::getOpenFileName(this, ("打开文档文件"),"./",tr("文档后缀(*.*)"));
    qDebug()<<fileName;
    label_selepath->clear();
    label_selepath->setText(fileName);
    textdis->append(QString("%1,%2:%3").arg(QTime::currentTime().toString("HH:mm:ss")).arg("已选择文件").arg(fileName));

    //获取并显示文件大小
    QFileInfo *pcsfileInfo = new QFileInfo(fileName);
    dataLen = pcsfileInfo->size ();
    textdis->append(QString("%1,%2:%3").arg(QTime::currentTime().toString("HH:mm:ss")).arg("文件大小").arg(dataLen));
}


/**
 * @brief UpdateWidget::onBtnLoadClicked
 */
void UpdateWidget::onBtnLoadClicked()
{
    if(fileName.isEmpty())
    {
      textdis->append(QString("%1,%2").arg(QTime::currentTime().toString("HH:mm:ss")).arg("请先选择文件!"));
    }
    else
    {
        readfile();
        DLoadBar->setRange(0,total); //设置进度条最小值和最大值(取值范围)
        textdis->append(QString("%1,%2").arg(QTime::currentTime().toString("HH:mm:ss")).arg("开始下载!"));
        emit viewTransmitData("FirmWare", "Download", loadStringList->at(0), 1);
//        downLoadFlag = true; //打开下载标志位
        timer->start(100); //打开定时器
    }
}


void UpdateWidget::readfile()
{
    //读取文件
    binFile = new QFile(fileName);
    binFile->open (QIODevice::ReadOnly);
    allDataArray = binFile->readAll();

    //1.初始化计数参数和存储容器
    int crc=0, length=512, listSeq=1;
    QString datastring;
    QByteArray temdata;
    loadStringList = new QStringList;
    int binfileseek = 0;

    //计算下载数据包数量total
    if(dataLen%512 >0)
    { total = (dataLen/512)+1; }
    else
    { total = dataLen/512;  }
    textdis->append(QString("%1,%2").arg(QTime::currentTime().toString("HH:mm:ss")).arg("开始读取!"));

    //2.1 装填发送包
    for(int i=0; i<=total; i++)
    {
        if(binfileseek >= dataLen) //2.1.1 已经全部装填
        {
            textdis->append(QString("%1,%2").arg(QTime::currentTime().toString("HH:mm:ss")).arg("读取完成!"));
            binfileseek = 0;
            allDataArray.clear();
            binFile->close();
        }
        else if((dataLen-binfileseek) > length) //2.1.2 还有大于一包没装填
        {
            for (int i=0; i<length; i++, binfileseek++)
            { temdata[i] = allDataArray.at(binfileseek); }
        }
        else  //2.1.3 还有最后一包没装填
        {
            int lastdata = dataLen-binfileseek;
            for (int i=0; i<lastdata; binfileseek++, i++)
            { temdata[i] = allDataArray.at(binfileseek); }
        }
        //2.1.4 发送包格式转换
        datastring.prepend(temdata);
        temdata.clear();
        Command *cmd = new Command;
        QString loadData = cmd -> prepareLoadingData(QString(total), QString(listSeq), QString(crc), datastring);
        datastring.clear();
        loadStringList->append(loadData);
        loadData.clear();
        listSeq++;
        qDebug() << "loadStringList:" << loadStringList->at(i);
    }
}


/**
* @projectName   TBoxSoft
* @brief         定时器处理子函数,定时发送数据
* @author        chenfuhao
* @date          2019-12-11
*/
void UpdateWidget::timerSend()
{
    static int seq=1, sendHistory=0;

    //3 判断对方上一个包回复结果,决定是否发送当前包
    if(resultValue ==0 && seqValue == seq && nextValue == seq+1) // 3.1 收到正常回复,继续判断是否发送下一个包
    {
        if(seqValue < total) // 发送未结束,发送下一个包
        {
            seq++; // 包序号增加
            emit viewTransmitData("FirmWare", "Download", loadStringList->at(seq-1), 1);
            DLoadBar->setValue(seqValue); //设置当前进度条值
            textdis->append(QString("%1,已发送:当前/总数= %2/%3").arg(QTime::currentTime().toString("HH:mm:ss")).arg(seq).arg(total));
            textdis->moveCursor(QTextCursor::End); //textdis显示最新消息
        }
        else  // 发送完成,更新状态,停止发送
        {
            DLoadBar->setValue(int(total)); //设置当前的运行值为100%
            textdis->append(QString("%1,%2").arg(QTime::currentTime().toString("HH:mm:ss")).arg("下载完成!"));
            textdis->moveCursor(QTextCursor::End); //textdis显示最新消息
            loadStringList->clear();
            seq = 1;
            retryNum = 0;
            timer->stop();
            return;
        }
    }
    else if(resultValue == 1) //3.2 设备处理结果为“失败”
    {
        textdis->append(QString("%1,%2").arg(QTime::currentTime().toString("HH:mm:ss")).arg("接收设备处理数据包失败,终止下载!"));
        loadStringList->clear();
        seq = 1;
        retryNum = 0;
        timer->stop();
        return;
    }
    if(signalType == 4) //3.3 接收回复超时处理,signalType为超时标志位
    {
        signalType = 0;
        //判断是否为当前包超时,是当前包则继续计数,不是当前包则重新计数
        if(sendHistory != nextValue)
        {
            sendHistory = nextValue;
            retryNum = 0;
            retryNum++;
            textdis->append(QString("%1,当前包回复超时次数为:%2").arg(QTime::currentTime().toString("HH:mm:ss")).arg(retryNum));
        }
        else {
            retryNum++;
            textdis->append(QString("%1,当前包回复超时次数为:%2").arg(QTime::currentTime().toString("HH:mm:ss")).arg(retryNum));
        }
        //判断当前包超时次数,超过5次则放弃下载
        if(retryNum > 5)
        {
            textdis->append(QString("%1,%2").arg(QTime::currentTime().toString("HH:mm:ss")).arg("对方无回复,终止下载!"));
            loadStringList->clear();
            retryNum = 0;
            timer->stop();
            return;
        }
        //判断当前下载包序号,有针对性重发,nextValue初始为0,收到第一个回复则变为2
        if(nextValue == 0)
        {
            emit viewTransmitData("FirmWare", "Download", loadStringList->at(0), 1);
        }
        else
        {
            emit viewTransmitData("FirmWare", "Download", loadStringList->at(nextValue-1), 1);
        }
    }

}
发布了11 篇原创文章 · 获赞 9 · 访问量 679

猜你喜欢

转载自blog.csdn.net/yimuta9538/article/details/103592010