首页 > 其他分享 >Qt使用QJson进行Http请求时序列反序列对象

Qt使用QJson进行Http请求时序列反序列对象

时间:2022-10-26 10:55:15浏览次数:57  
标签:machineCoords set CMAKE Qt const mm 序列 Http 4.0

1. 创建工程

  • 使用CMake创建工程

    cmake_minimum_required(VERSION 3.20 FATAL_ERROR)
    
    project(httprequest LANGUAGES CXX)
    
    set(CMAKE_AUTOUIC ON)
    set(CMAKE_AUTOMOC ON)
    set(CMAKE_AUTORCC ON)
    
    set(CMAKE_CXX_STANDARD 20)
    set(CMAKE_CXX_EXTENSIONS OFF)
    set(CMAKE_CXX_STANDARD_REQUIRED ON)
    
    set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/bin")
    set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/bin")
    set(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/lib")
    
    set(QT_VERSION_STR_Win32 "5.15.2/msvc2019")
    set(QT_VERSION_STR_Win64 "5.15.2/msvc2019_64")
    
    if(CMAKE_HOST_WIN32)
      if(CMAKE_CL_64)
        set(CMAKE_PREFIX_PATH ${CMAKE_PREFIX_PATH} "D:/Qt/${QT_VERSION_STR_Win64}")
        set(QT_QMAKE_EXECUTABLE "D:/Qt/${QT_VERSION_STR_Win64}/bin/qmake.exe")
      else()
        set(CMAKE_PREFIX_PATH ${CMAKE_PREFIX_PATH} "D:/Qt/${QT_VERSION_STR_Win32}")
        set(QT_QMAKE_EXECUTABLE "D:/Qt/${QT_VERSION_STR_Win32}/bin/qmake.exe")
      endif()
    endif()
    
    set(EXPAN_MACRO OFF)
    if(EXPAN_MACRO)
      if(MSVC)
        add_compile_options(/P /EP)
      endif(MSVC)
    endif()
    
    add_executable(${CMAKE_PROJECT_NAME} "")
    # add_executable(${CMAKE_PROJECT_NAME} WIN32 "")
    
    file(GLOB srcs CMAKE_CONFIGURE_DEPENDS *.cpp)
    file(GLOB headers CMAKE_CONFIGURE_DEPENDS *.h)
    file(GLOB forms CMAKE_CONFIGURE_DEPENDS *.ui)
    file(GLOB resources CMAKE_CONFIGURE_DEPENDS *.qrc)
    
    target_sources(${CMAKE_PROJECT_NAME} PRIVATE ${srcs} ${forms} ${resources})
    target_include_directories(${CMAKE_PROJECT_NAME} PRIVATE ${headers})
    
    find_package(Qt5 COMPONENTS Core Widgets Network REQUIRED)
    
    target_link_libraries(${CMAKE_PROJECT_NAME}
    	PRIVATE 
      Qt5::Core Qt5::Widgets Qt5::Network
    )
    
  • 引入QJson

    add_subdirectory(qjson)
    find_package(Qt5 COMPONENTS Core Widgets Network REQUIRED)
    
    target_link_libraries(${CMAKE_PROJECT_NAME}
      PRIVATE 
      Qt5::Core Qt5::Widgets Qt5::Network
      qjson-qt5
    )
    
  • 创建相应的头、源文件

    .
    ├── [1.7K]  CMakeLists.txt
    ├── [ 26K]  CMakeLists.txt.user
    ├── [4.0K]  build
    │   ├── [ 27K]  ALL_BUILD.vcxproj
    │   ├── [ 290]  ALL_BUILD.vcxproj.filters
    │   ├── [ 18K]  CMakeCache.txt
    │   ├── [4.0K]  CMakeFiles
    │   ├── [4.0K]  Debug
    │   ├── [ 10K]  INSTALL.vcxproj
    │   ├── [ 532]  INSTALL.vcxproj.filters
    │   ├── [ 19K]  UpgradeLog.htm
    │   ├── [ 29K]  ZERO_CHECK.vcxproj
    │   ├── [ 533]  ZERO_CHECK.vcxproj.filters
    │   ├── [4.0K]  bin
    │   ├── [1.6K]  cmake_install.cmake
    │   ├── [4.0K]  httprequest.dir
    │   ├── [5.9K]  httprequest.sln
    │   ├── [ 57K]  httprequest.vcxproj
    │   ├── [3.2K]  httprequest.vcxproj.filters
    │   ├── [4.0K]  httprequest_autogen
    │   ├── [4.0K]  lib
    │   ├── [4.0K]  qjson
    │   └── [4.0K]  win32
    ├── [ 102]  cncposition.cpp
    ├── [3.9K]  cncposition.h
    ├── [ 209]  main.cpp
    ├── [2.5K]  mainwindow.cpp
    ├── [ 319]  mainwindow.h
    ├── [1.2K]  mainwindow.ui
    └── [4.0K]  qjson
        ├── [6.4K]  CMakeLists.txt
        ├── [ 26K]  COPYING.lib
        ├── [3.8K]  ChangeLog
        ├── [ 195]  QJSONConfig.cmake.in
        ├── [ 477]  QJSONConfigVersion.cmake.in
        ├── [ 390]  QJson.pc.in
        ├── [3.1K]  README.license
        ├── [3.4K]  README.md
        ├── [4.0K]  build
        ├── [ 750]  cmake_uninstall.cmake.in
        ├── [4.0K]  doc
        ├── [4.0K]  include
        ├── [4.0K]  src
        └── [4.0K]  tests
    

3. 定义有动态列表的对象模型

  • cncposition.h

    #ifndef CNCPOSITION_H
    #define CNCPOSITION_H
    
    #include <QObject>
    #include <QVector>
    #include <QList>
    #include <QStringList>
    #include <QVariantList>
    #include <QDebug>
    
    class CncPosition : public QObject
    {
        Q_OBJECT
    
        // Q_PROPERTY(int code READ code WRITE setCode)
        // Q_PROPERTY(QString message READ message WRITE setMessage)
    
        Q_PROPERTY(QStringList axis READ axis WRITE setAxis)
        Q_PROPERTY(QStringList units READ units WRITE setUnits)
        Q_PROPERTY(QVariant absoluteCoords READ absoluteCoords WRITE setAbsoluteCoords)
        Q_PROPERTY(QVariant relativeCoords READ relativeCoords WRITE setRelativeCoords)
        Q_PROPERTY(QVariant machineCoords READ machineCoords WRITE setMachineCoords)
        Q_PROPERTY(QVariant distances READ distances WRITE setDistances)
    
    public:
        explicit CncPosition(QObject *parent = nullptr);
    
        // int code() const { return _code; }
        // void setCode(int code) { _code = code; }
    
        // QString message() const { return _message; }
        // void setMessage(QString &message) { _message = message; }
    
        QStringList axis() const { return _axis; }
        void setAxis(const QStringList &axis)
        {
            // qDebug() << axis;
            _axis = axis;
        }
    
        QStringList units() const { return _units; }
        void setUnits(const QStringList &units)
        {
            // qDebug() << units;
            _units = units;
        }
    
    private:
        QVariant absoluteCoords() const { return QVariant::fromValue(_absoluteCoords); }
        QVariant relativeCoords() const { return QVariant::fromValue(_relativeCoords); }
        QVariant machineCoords() const { return QVariant::fromValue(_machineCoords); }
        QVariant distances() const { return QVariant::fromValue(_distances); }
    
    public:
        QList<double> getAbsoluteCoords() const { return _absoluteCoords; }
        void setAbsoluteCoords(const QVariant &absoluteCoords)
        {
            _absoluteCoords.clear();
            for (auto var: absoluteCoords.toList()) {
                _absoluteCoords.append(var.toDouble());
            }
        }
    
        QList<double> getRelativeCoords() const { return _relativeCoords; }
        void setRelativeCoords(const QVariant &relativeCoords)
        {
            _relativeCoords.clear();
            for (auto var : relativeCoords.toList()) {
                _relativeCoords.append(var.toDouble());
            }
        }
    
        QList<double> getMachineCoords() const {return _machineCoords;}
        void setMachineCoords(const QVariant &machineCoords)
        {
            _machineCoords.clear();
            for (auto var : machineCoords.toList()) {
                _machineCoords.append(var.toDouble());
            }
        }
    
        QList<double> getDistences() const {return _distances;}
        void setDistances(const QVariant &distances)
        {
            _distances.clear();
            for (auto var : distances.toList()) {
                _distances.append(var.toDouble());
            }
        }
    
    public:
        friend QDebug operator<<(QDebug dbg, const CncPosition &p)
        {
            // dbg.nospace() << "code:" << p.code() << "message:" << p.message()
            //               << "Axis:" << p.Axis() << "Units:" << p.Units() << "AbsoluteCoords:" << p.AbsoluteCoords()
            //               << "RelativeCoords:" << p.RelativeCoords() << "MachineCoords:" << p.MachineCoords()
            //               << "Distances:" << p.Distances();
    
            // dbg << "code:" << p.code() << "message:" << p.message()
            dbg << "Axis:" << p.axis() << "Units:" << p.units() << "AbsoluteCoords:" << p.getAbsoluteCoords()
                << "RelativeCoords:" << p.getRelativeCoords() << "MachineCoords:" << p.getMachineCoords()
                << "Distances:" << p.getDistences();
    
            return dbg;
        }
    
    signals:
    
    private:
        // int _code;
        // QString _message;
        QStringList _axis;
        QStringList _units;
        QList<double> _absoluteCoords;
        QList<double> _relativeCoords;
        QList<double> _machineCoords;
        QList<double> _distances;
    };
    
    #endif // CNCPOSITION_H
    

4. 运行验证

在mainwindow这个Widget中定义了一个PushButtton和一个用于显示请求到的application/json;charset=utf-8Content-Type, 下面时验证代码,将QNetworkAccessManager使用同步的方式取结果

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

    connect(ui->pushButton, &QPushButton::clicked, this, [=]
            {

        std::unique_ptr<QNetworkAccessManager> manager = std::make_unique<QNetworkAccessManager>(new QNetworkAccessManager());
        QUrlQuery urlQuery;
        urlQuery.addQueryItem("fcode", "CNC_POSITION");
        QUrl url("http://127.0.0.1:9001/das/services/pull?" + urlQuery.query(QUrl::FullyDecoded));
        QNetworkRequest request(url);
        request.setHeader(QNetworkRequest::KnownHeaders::ContentTypeHeader, "application/json;charset=utf-8");

        QNetworkReply *reply = manager->get(request);
        QEventLoop eloop;
        QObject::connect(reply, &QNetworkReply::finished, &eloop, &QEventLoop::quit);
        eloop.exec(QEventLoop::ExcludeUserInputEvents);

        auto jstr = reply->readAll();

        // QString text = "{\"axis\":[\"X\",\"Y\",\"Z\",\"A\",\"U\"],\"units\":[\"mm\",\"mm\",\"mm\",\"ang\",\"mm\"],\"absoluteCoords\":[33,-768,98.7,99,0],\"relativeCoords\":[33,-768,98.7,99,0],\"machineCoords\":[33,-768,98.7,99,0],\"distances\":[0,0,0,0,0]}";

        QJson::Parser parser;
        parser.specialNumbersAllowed();
        bool ok = false;
        auto variant = parser.parse(jstr, &ok);
        // auto variant = parser.parse(text.toUtf8(), &ok);
        if (!ok)
        {
            qWarning() << parser.errorString();
            return;
        }

        // 返回值检查
        auto map = variant.toMap();
        int code = map["code"].toInt();
        if (code != 0)
        {
            qWarning() << map["message"].toString();
            return;
        }

        // 反序列化到对象实列
        CncPosition position;
        QJson::QObjectHelper::qvariant2qobject(map["data"].toMap(), &position);

        qDebug() << position;

        ui->textEdit->setText(jstr);
        reply->deleteLater(); });
}
  • 后端返回的Json内容如下

    {"code":0,"message":"成功","data":{"axis":["X","Y","Z","A","U"],"units":["mm","mm","mm","ang","mm"],"absoluteCoords":[33,-768,98.7,99,0],"relativeCoords":[33,-768,98.7,99,0],"machineCoords":[33,-768,98.7,99,0],"distances":[0,0,0,0,0]}}
    
  • 最终执行程序验证,通过cncpostion类中重载的<<操作符,输出结果

    Axis: ("X", "Y", "Z", "A", "U") Units: ("mm", "mm", "mm", "ang", "mm") AbsoluteCoords: (33, -768, 98.7, 99, 0) RelativeCoords: (33, -768, 98.7, 99, 0) MachineCoords: (33, -768, 98.7, 99, 0) Distances: (0, 0, 0, 0, 0)
    

5. 结论

  • QJson来进行对象的序列、反序列化非常的方便,提高了程序的可读性与开发效率

  • 服务端序列化Key值使用小驼峰方式,二者之间必须明确协议,服务端能够兼容到不区分大小写的Key值,通过实际使用中发现QJsonKey值大小写敏感,否则QJson::QObjectHelper::qvariant2qobject会失败

  • 能注意到cncpostionQ_PROPERTY的部分的操作类型必须保持一致,否则Qt Moc(Meta-Object Compiler)会出错,但是Moc并不会限制READ、WRITE部分的访问权限,猜测是做的模板生成与字符方面的处理,这样可以让需要序列、反序列部分使用QJson解析支持的QVariant, 然后公开出去的Get属性返回最终的使用类型。

标签:machineCoords,set,CMAKE,Qt,const,mm,序列,Http,4.0
From: https://www.cnblogs.com/linxmouse/p/16827511.html

相关文章

  • QT MySQL连接自动断开
    参考链接MySQL链接10天后自动断开解决方案:<https://blog.csdn.net/xiaoxiao133/article/details/123006881方式一QT中可以通过自动重连的方式进行配置,如下所示:QSqlData......
  • httprunner 2.x学习20 - env环境变量有#注释和空行处理
    前言httprunner用.env文件管理环境变量,但是必须是严格是key=value格式,如果加#注释就会用例解析失败。问题描述问题版本:v2.5.9问题描述:.env文件中带有#号注释#用户......
  • httprunner 创建项目
    1、pipinstallhttprunner结果:安装成功hrun-VV4.3.02、hrun--startprojectdir提示:找不到startproject httprunnerstartprojectdir(hrp3.x创建项目命令)提示......
  • okHttp3集成
    Maven依赖pom:<dependency><groupId>com.squareup.okhttp3</groupId><artifactId>okhttp</artifactId><version>4.9.0</version></dependency>代码:pac......
  • GitHub Pages站点官方宣布开始使用HTTPS
    数百万人依靠GitHubPages,将其作为他们的网站主机,除此之外,还有数百万人每天访问这些网站。为了更好地保护到GitHubPages站点的通讯,也为了鼓励在因特网上更广泛地采用HT......
  • Http的基本概念和maven的学习
    1:什么是HTTP(1)HTTP(超本文传输协议)是一个简单的请求-响应协议(2)HTTP的默认端口是80,HTTPS是443(安全的)2:http的两个时代(1)http1.0:客户端可以与web服务器链接后,......
  • 剑指 Offer 37. 序列化二叉树 - 力扣(LeetCode)
    剑指Offer37.序列化二叉树-力扣(LeetCode)题目大意:将一棵二叉树序列化成字符串,然后通过该字符串可以重新构造出二叉树思路:看到将二叉树转化成字符串,首先想到的......
  • 算法】字符串复原IP地址,从前序与中序编辑序列构造二叉树
    算法学习有些时候是枯燥的,一点一点学习算法第一题算法题目描述对给定的两个日期之间的日期进行遍历,比如startTime是2014-07-11;endTime是2014-08-11如何把他们之间......
  • HttpWebRequest请求
    1.获取token接口1privatestringgettoken()2{3//测试环境登陆用户4//stringusername="as";5//string......
  • Unable to configure HTTPS endpoint
    ASP.net开发完成以后,目标机上只需要安装aspnetcore-runtime 加dotnet-runtime就可以跑起来了,但是如果还采用了https的方式,此时发现System.InvalidOperationExceptio......