QT timer to achieve an interactive file to download, receive a package, issued a

Child thread receives data through, then transmitted to each page, the function parses the received data, according to the analysis result delivered by the timer.

Current check code is not added, may be operating normally.

The main function is as follows:

/**
 * @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);
        }
    }

}

 

Published 11 original articles · won praise 9 · views 679

Guess you like

Origin blog.csdn.net/yimuta9538/article/details/103592010