`
cutecoot
  • 浏览: 120406 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

QT下对硬件固件协议的测试小结及几个QT遇到的问题解决

阅读更多

为基于网络udp通信的固件协议进行测试,用QT编写测试工具。其间遇到了一些问题,并逐个解决。特记录在此。

1. 因为基于网络协议,所以需要获取IP,方便发送并接收UDP数据。但因虚拟网卡等,所以需要筛选IP。

 

    QHostAddress addr;
    QList<QHostAddress> list = QNetworkInterface::allAddresses();
    foreach (addr, list)
    {
       if(addr.protocol() == QAbstractSocket::IPv4Protocol){
           if (addr.toString().contains("192.168")){
               address = QHostAddress(addr.toString());
           }
       }
    }

而在发送命令时,若是以广播方式发送,则也需要考虑使用哪块网卡进行广播。因此要先绑定ip。

udpCMDSocket = new QUdpSocket(this);
udpCMDSocket->bind(QHostAddress(ip));
udpCMDSocket->writeDatagram(cmd.toLocal8Bit(), HubAddr, port);

 

2. 当在主UI上临时需要做高占用的任务如while循环时,可以用QApplication::processEvents()来响应界面上的待处理事件。

 

while (!binFile.atEnd() {
                QByteArray byte = binFile.read(len);
                。。。
                sendCMD2Port(cmd, HubAddr, port);
                Sleep(interval);
                QApplication::processEvents();
            }

 3. 打开文件,若已有路径显示已有路径

    QString tmpBinfile;
    if (BinFilePath.size() == 0)
        tmpBinfile = QFileDialog::getOpenFileName(this, tr("Open Bin File"), ".", tr("Bin File(*.bin)"));
    else
        tmpBinfile = QFileDialog::getOpenFileName(this, tr("Open Bin File"), BinFilePath, tr("Bin File(*.bin)"));

 4. 读取文件,生成QListWidget,并排序

bool CaseInsSort(const QString &info1, const QString &info2)
{
    return info1.toLower() < info2.toLower();
}

void loadCases()
{
    QFile file(filename);
    if (file.open(QFile::ReadWrite|QIODevice::Text)){
        QTextStream data(&file);
        QStringList fonts;
        QString line1;
        QString line2;
        while (!data.atEnd()){
            line1 = data.readLine();
            line2 = data.readLine();
            fonts<<line1;
            caseHash.insert(line1,line2);
        }
        qSort(fonts.begin(), fonts.end(), CaseInsSort);
        caseList->addItems(fonts);//把各行添加到listwidget
        file.close();
    }
}

 5. QListWidgetItem改名

void renameCase()
{
    QListWidgetItem *caseItem = caseList->currentItem();
    if (caseItem){
        caseList->openPersistentEditor(caseItem);
    }
}

 6. 发送UDP命令

void sendCMD2Port(QString cmd, QHostAddress HubAddr, int port)
{
    udpCMDSocket = new QUdpSocket(this);
    udpCMDSocket->writeDatagram(cmd.toLocal8Bit(), HubAddr, port);
    udpCMDSocket->close();
}

 7. 监听线程独立于主线程,包括对监听数据处理都在run中

void listenPortThread::run()
{
    QUdpSocket udpListenSocket;
    bool result = udpListenSocket.bind(address, port,QUdpSocket::ShareAddress);//绑定到指定的端口号
    if(!result)//若绑定不成功,给出出错信息
    {
        udpListenSocket.close();
        stop();
        return;
    }
    islisten = true;
    m_bStop = false;
    while(!m_bStop)
    {
        QByteArray array;
        QHostAddress address;
        quint16 port;
        if (islisten){
            while (udpListenSocket.hasPendingDatagrams()) {
                array.resize(udpListenSocket.pendingDatagramSize());//根据可读数据来设置空间大小
                udpListenSocket.readDatagram(array.data(),array.size(),&address,&port); //读取数据
                QString str = array;
                。。。

 8.单次定时器控制,判断是否在时限内收到回复。到时间在timeout函数中判断。

       QTimer::singleShot(1500,this,SLOT(timeout()));
        sendCMD2Port(cmd, HubAddr, port);

 9. 解析收到的json回复,通过关键字查询结果

bool listenPortThread::parseJson(QByteArray array, QString *sendID, QString *result, QString key){
    QJsonParseError jsonError;
    QJsonDocument doucment = QJsonDocument::fromJson(array, &jsonError);  // 转化为 JSON 文档
    if (!doucment.isNull() && (jsonError.error == QJsonParseError::NoError)) {  // 解析未发生错误
        if (doucment.isObject()) { // JSON 文档为对象
            QJsonObject object = doucment.object();  // 转化为对象
            if (!key.isEmpty() && object.contains(key)){
                QJsonValue Jvalue = object.value(key);
                if (Jvalue.isString()) { 
                    QString strvalue = Jvalue.toString();
                    *result = strvalue;
                }
            }

 10. 返回的json数据,包括base64数据时,解码并还原为float

QJsonValue Jdata = object1.value("data");
if (Jdata.isString()) {  
    QString strdata = Jdata.toString();
    QByteArray Hex = QByteArray::fromBase64(strdata.toLatin1()).toHex();
    QString calidata = "";
    for (int i=0; i<12; i++){
        QString str =Hex.mid(i*8+6,2)+Hex.mid(i*8+4,2)+Hex.mid(i*8+2,2)+Hex.mid(i*8,2); //低位到高位
        int iHex = str.toUInt(0,16);
        float fHex = *(float*)&iHex ;
        calidata += QString("%1, ").arg(fHex);
    }
    *result = calidata;
}

11. 在pro文件中通过VERSION设定APP版本号,并在程序中获取APP版本号

写道
In the YourApp.pro:

VERSION = 0.0.0.1
DEFINES += APP_VERSION=\\\"$$VERSION\\\"

In the main.cpp:

#include <QApplication>
QCoreApplication::setApplicationVersion(QString(APP_VERSION));

Wherever else in your sources, e.g. in the imaginary controller.cpp:

#include <QApplication>
QString yourAppVersion = QCoreApplication::applicationVersion();

 

12. 发布release版本程序,自动打包QT所需动态库

写道
Qt官方开发环境默认使用动态链接库方式,在发布生成的可执行程序时,我们需要复制一大堆动态库,如果自己去复制动态库,很可能丢三落四,导致程序在别的电脑里无法正常运行。 因此 Qt 官方开发环境里自带了一个部署工具来帮助开发者自动拷贝大部分的依赖库。

Windows开发环境下windeployqt工具 (如果你已经将Qt的bin目录加入PATH环境,那么你可以直接在命令行使用windeployqt调用.)。首先,将项目中的release文件中的可执行文件拷到一个新建的文件夹中,例如project.exe,用Qt自带的生成必备的dll文件的程序windeployqt,来把必要的动态库拷到该文件夹中,打开命令行,输入windeployqtproject.exe,这时候大部分的dll文件都自动拷贝过来了,但是如果项目还用了一些其他的SDK,比如OpenCV,Chartdir51等等,就需要手动将所需dll拷贝过来,如果不知道还需要哪些软件,可以用Dependency Walker来查看缺少哪些dll文件。

注意:如果发布的应用是Qt Quick Application应用,那么命令行需要加上QML的安装目录。命令中的D:\Qt\Qt5.5.1\qml是qml的安装目录,请换成你自己的qml安装目录!!!!!

windeployqt hello.exe --qmldir D:\Qt\Qt5.5.1\qml

接下来要高大上的朋友就可以用Enigma VirtualBox软件虚拟化工具将多个文件封装到应用程序主文件,从而制作成为单执行文件的绿色软件。

 
13. 制作多语言版,使用QT linguist做语言包
写道
1. 在pro文件中添加TRANSLATIONS += filename_CN.ts
2. 工具-->外部-->linguist-->更新,来生成ts文件。但若直接使用,则qt可能会报错。因为没有找到VS的环境。所以

a. Create a translate.bat with the following single-line content:

"%programfiles(x86)%\Microsoft Visual Studio\2017\Community\VC\Auxiliary\Build\vcvars64.bat" & lupdate.exe %1

and put it under %{CurrentProject:QT_INSTALL_BINS} (in my case C:\Qt\Qt5.9.1\5.9.1\msvc2017_64\bin). Make sure that the translate.bat contains the correct path to vcvars64.bat on your machine. You may as well put another version of vcvars if you need.

b. In Qt Creator select Tools/Options/Environment/External Tools and then Add Tool under Linguist category. Name it something like Create/Update TS files. Setup the fields for this entry as follows:

Executable: %{CurrentProject:QT_INSTALL_BINS}\translate.bat,

Arguments: %{CurrentProject:FilePath},

Working directory: %{CurrentProject:QT_INSTALL_BINS},

as shown here: External Tools, then apply the changes and close the Options window.

c. Go to Tools/External/Linguist, select Create/Update TS files and now it should do the job as usual.

3. 在linguist中编辑ts文件,加语言翻译
4. 在linguist直接发布,或用qt的工具-->外部-->linguist-->发布,来用ts文件生成qm文件
5. 在主程序中
     QApplication app(argc, argv);
     QTranslator translator;
     bool ok=translator.load(":/qm/filename_CN.qm");
     app.installTranslator(&translator);

 

14. qt全局宏变量

写道
pro中添加如下宏定义代码:

     DEFINES += HELLO=\\\"$$PWD/\\\"
     DEFINES += SUCCESS=\\\"string\\\"

在.cpp中测试代码如下:

     #ifdef HELLO
     qDebug()<<"HELLO="<<HELLO;
     #else
     qDebug()<<"bye";
     #endif

 

分享到:
评论

相关推荐

    Qt串口12313123123_串口协议解析_qt串口_QT_QT协议解析_Qt串口

    在本文中,我们将深入探讨如何使用Qt库进行串口通信以及串口协议解析。Qt是一个跨平台的应用程序开发框架,广泛应用于C++编程,尤其在GUI应用中表现出色。而串口通信是设备间通过串行接口进行数据传输的一种常见方式...

    基于qt的ymodem协议上位机实现

    实现基于Qt的YModem上位机,主要涉及到以下几个关键知识点: 1. **Qt串口通信**:Qt提供QSerialPort模块,用于处理串口通信。我们需要配置串口参数,如波特率、数据位、停止位、校验位等,然后打开串口并监听数据。...

    基于Qt5.11硬件信息获取

    Qt5.11是该框架的一个版本,它提供了许多改进和新特性,包括更高效的性能、更好的图形渲染以及对现代硬件的支持。本文将详细讨论如何在Qt5.11环境下获取硬件信息。 首先,Qt5.11为开发者提供了丰富的API,可以用于...

    【QT】自定义协议解决TCP粘包和拆包问题

    本文将详细介绍如何使用QT来设计一个自定义协议,以解决TCP粘包和拆包的问题。 首先,我们需要理解TCP粘包和拆包的原因。TCP为了提高传输效率,会将较小的数据包合并成一个大包发送,或者将一个大的数据包拆分成多...

    Qt绑定开发板硬件按键

    在嵌入式系统开发领域,将Qt框架与硬件设备(如ARM开发板)结合使用时,一个常见的需求是实现对硬件按键的绑定与响应。本文旨在深入探讨如何在Qt中绑定ARM开发板上的硬件按键,并通过代码示例详细阐述其实现过程。 ...

    Qt spi测试

    文件名`qt_spidev_test-master`可能是一个包含Qt SPI设备测试示例的项目。在这个项目中,你可能会找到一个名为`SpiDev`的类,它实现了上述的SPI操作,以及一个Qt GUI,用于用户交互。通过查看和运行这个项目,你可以...

    基于qt5下的modbus协议库

    **标题解析:** "基于qt5下的modbus协议库" 指的是一个使用Qt5框架开发的Modbus协议库。Modbus是一种广泛使用的工业通信协议,尤其在自动化设备和系统中,它允许设备间进行数据交换。而这里的库是为Qt5设计的,意味...

    qt uvc摄像头测试

    QT UVC(Universal Video Class)摄像头测试涉及到的是在Qt框架下使用USB视频类设备进行视频输入的操作。Qt是一个跨平台的C++图形用户界面应用程序开发框架,广泛应用于桌面、移动和嵌入式设备的开发。UVC是USB设备...

    SerialPortYmodem-master_QT上位机YMode_Ymode_Ymode协议qt_

    YModem协议是XModem协议的改进版,主要解决了XModem协议中单个块传输错误率较高的问题。YModem协议采用了分块传输和校验的方式,每次传输多个数据块,并在接收端进行校验,提高了文件传输的可靠性。在QT框架下,我们...

    基于Qt的ARM Linux 平台图形界面系统测试工具

    描述中的"基于Qt的ARM Linux 平台图形界面系统测试工具"是对标题的进一步强调,暗示这个工具的主要功能是进行系统测试,而且专为ARM Linux环境设计,具备图形化操作界面,使得测试过程更加直观和便捷。 【标签解析...

    linux下qt_creator的安装及测试

    ### Linux下Qt Creator的安装与测试 #### 一、引言 随着开源软件的日益普及和发展,越来越多的开发者开始关注并使用Qt库进行跨平台应用的开发。Qt因其丰富的功能特性,良好的性能表现以及强大的社区支持,成为了...

    QT 获取USB信息

    QT框架是一种跨平台的应用程序开发框架,主要使用C++语言编写,广泛应用于GUI(图形用户界面)应用程序的开发。在本项目"QT获取USB信息"中,我们将探讨如何利用QT来获取并显示USB设备的相关信息。这个项目包含了一个...

    Qt实现的XModem和YModem协议源码

    Xmodem协议传输有接收程序和发送程序完成,先由接收程序发送协商字符,协商校验方式,协商通过之后发送程序就开始发送数据包,接收程序接收到完整的一个数据包之后按照协商的方式对数据包进行校验。校验通过之后发送...

    Ymodem固件更新上位机-qt版本.rar

    Ymodem固件更新上位机,串口程序(c++),qt5.11.0 mingw32位. 实现的上位机,没有在正规的Ymodem下位机上尝试过。看网络资料,起始包的里的文件长度是16进制字符串,本程序用的是10进制字符串。有点类似超级终端。

    基于ARM的QT开发环境搭建及验证测试

    在本教程中,我们将探讨如何在Ubuntu 20.04系统上建立一个基于ARM的Qt开发环境,并进行相应的验证测试。主要涉及的步骤包括Qt源码的编译、生成交叉编译的qmake文件和Qt依赖库,以及在Xilinx ZYNQ芯片上的嵌入式库...

    海思3519 QT移植测试程序

    这里我们主要探讨如何在海思3519芯片上移植和测试QT应用,以及在这个过程中可能遇到的关键步骤和问题。 首先,QT(Qt)是一个跨平台的应用程序开发框架,广泛用于构建图形用户界面(GUI)。由于3519是海思公司的一...

    QT嵌入式汽车仪表测试

    这个压缩包文件包含了三个汽车仪表盘测试代码示例,这些代码可能涵盖了以下几个关键知识点: 1. **QT GUI设计**:使用QT Designer工具创建用户界面布局,包括速度表、转速表、油量表等汽车仪表组件,通过QT的信号和...

    基于Qt creator 实现ymodem协议 通过串口传输文件 可以用来做串口升级的功能等等 代码简单 容易懂.zip

    在本文中,我们将深入探讨如何使用Qt Creator实现Ymodem协议,通过串行端口进行文件传输,并讨论这种技术在设备固件升级等场景中的应用。Ymodem是一种古老的但仍然广泛使用的文件传输协议,特别是在低带宽或不稳定的...

    qt串口下载bin固件例子

    在本文中,我们将深入探讨如何使用Qt框架进行串口通信,并以"qt串口下载bin固件例子"为例,讲解如何实现自动检测串口、CRC校验以及显示下载进度的功能。Qt是一个强大的C++图形用户界面库,适用于多种平台,包括...

Global site tag (gtag.js) - Google Analytics