QT文件下载,收发对话,子线程接收函数实现

文件读取在下载按钮点击之后完成,通过Jeson已经转换成需要的字符串格式。

将字符串统一存储到QStringList中,下载的时候,对话正确则发送下一个包。

如果超时,则显示超时次数,超时第六次不再重发,直接终止。

/**
 * @brief appendToRecord
 * @param array
 * @param type
 *  RECORD_ALL = 0,
    RECORD_SEND = 1,
    RECORD_RECV = 2,
    RECORD_REPORT = 3,
    RECORD_TIMEOUT = 4
 */
void UpdateWidget::appendToRecord(const QByteArray &array, int type)
{
    static int historyValue = 0;
    if(downLoadFlag == true)
    {
        QJsonObject  json;
        if(type == 4) //3.3 接收回复超时处理
        {
            //判断是否为当前包超时,是当前包则继续计数,不是当前包则重新计数
            if(historyValue != nextValue)
            {
                historyValue = 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;
                downLoadFlag = false;
                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);
            }
        }
        if(arrayToJsonObject(QString(array), json))
        {
            //1、检测ident字段是否为 "FirmWare"
            if((jsonIdentCheck(TBox_Download_TAG, json) != false)
                    && (jsonMethodCheck(Method_Response, json) == true))
            {
                if(json.contains(TBox_Param_TAG) != true
                        || json.value(TBox_Param_TAG).isObject() != true)
                {
                    return ;
                }
                QJsonObject paramObj = json.value(TBox_Param_TAG).toObject();
                //2、读取消息中的值,根据回复情况继续下载或者终止下载
                resultValue = paramObj.value(Download_Result).toInt();//getStringValueByKey(Download_Result, json);
                if(resultValue == 0)
                {
                    seqValue = paramObj.value(Download_Seq).toInt();
                    nextValue = paramObj.value(Download_Next).toInt();
                    if(seqValue < total) // 发送未结束,发送下一个包
                    {
                        emit viewTransmitData("FirmWare", "Download", loadStringList->at(nextValue-1), 1);
                        DLoadBar->setValue(seqValue); //设置当前进度条值
                        textdis->append(QString("%1,已发送:当前/总数= %2/%3").arg(QTime::currentTime().toString("HH:mm:ss")).arg(seqValue).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();
                        downLoadFlag = false;
                        return;
                    }
                }
                else if(resultValue == 1)
                {
                    reasonValue = paramObj.value(Download_Reason).toString();
                    textdis->append(QString("%1,接收设备处理数据包失败,终止下载! reason:%2").
                                    arg(QTime::currentTime().toString("HH:mm:ss")).arg(reasonValue));
                    loadStringList->clear();
                    downLoadFlag = false;
                    return;
                }
            }
        }

    }
}

下面是下载按钮的动作。

1.判断是否有文件路径,如果有,读取文件;如果没有,让用户选择。

2.设置进度条大小,发送第一包数据。

3.开启下载标志位。

/**
 * @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; //打开下载标志位
    }
}

下面是文件读取的函数,文件选择已经在浏览按钮的动作下实现了。

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);
    }
}
发布了11 篇原创文章 · 获赞 9 · 访问量 678

猜你喜欢

转载自blog.csdn.net/yimuta9538/article/details/103592420
今日推荐