Qt 天气预报项目

参考引用

  • QT开发专题-天气预报

1. JSON 数据格式

1.1 什么是 JSON

  • JSON (JavaScript Object Notation),中文名 JS 对象表示法,因为它和 JS 中对象的写法很类似
    • 通常说的 JSON,其实就是 JSON 字符串,本质上是一种特殊格式的字符串
    • JSON 是一种轻量级的数据交换格式,客户端和服务端数据交互,基本都是 JSON 格式的
  • JSON 有以下特点
    • 便于阅读和书写
      • 除了 JSON 格式,还有一种数据传输格式 XML,相对于 XML,JSON 更加便于阅读和书写独立于编程语言
    • 网络传输的标准数据格式
    • 完全独立于编程语言
      • 几乎在所有的编程语言和开发环境中,都有解析和生成 JSON 字符串的库
    // C
    Jansson cJSON
    
    // C++
    jsonCpp、JSON for Modern C++
    
    // Java
    json-lib、org-json
    
    // Qt
    QJSONxxx
    

1.2 JSON 的两种数据格式

JSON 有两种数据格式

  • JSON 对象(被大括号包裹)
  • JSON 数组(被中括号包裹)
1.2.1 JSON 数组
  • JSON 数组格式
    [元素1, 元素2, 元素3, ... 元素n]
    
  • 类似于 c/C++ 中的数组,元素之间以逗号分隔。不同的是,JSON 数组中的元素可以是不同的数据类型
    • 包括:整型、浮点、字符串、布尔类型、JSON 数组、JSON 对象、空值
    // JSON 数组中的元素是同一类型
    [1, 2, 3, 4]
    ["Spring", "Summer", "Autumn", "Winter"]
    
    // JSON 数组中的元素是不同类型
    [1, 2.5, "hello", true, false, null]
    
    // JSON 数组的嵌套
    [
        [1, 2, 3, 4],
        ["Spring", "Summer", "Autumn", "Winter"],
        [1, 2.5, "hello", true, false, null]
    ]
    
    // JSON 数组嵌套 JSON 对象
    [
        {
            "name": "Tom",
            "age": 18,
            "gender": "male"
        }
        {
            "name": "Lucy",
            "age": 20,
            "gender": "female"
        }
    ]
    
1.2.2 JSON 对象
  • JSON 对象格式
    {
        "key1": value1,
        "key2": value2,
        "key3": value3
    }
    
  • JSON 对象内部使用键值对的方式来组织
    • 键和值之间使用冒号分隔,多个键值之间使用逗号分隔
    • 键是字符串类型,值的类型可以是:整型、浮点、字符串、布尔类型、JSON 数组、JSON 对象、空值
    {
        "name": "Tom",
        "age": 18,
        "gender": "male"
    }
    
  • JSON 对象中,还可以嵌套 JSON 对象和 JSON 数组
    {
        "name": "China",
        "info": {
            "capital": "beijing",
            "asian": true,
            "founded": 1949
        },
        "provinces": [{
            "name": "hunan",
            "capital": "changsha"
        }, {
            "name": "hubei",
            "capital": "wuhan"
        }]
    }
    

1.3 JSON 在线解析

  • JSON 本质就是一种特殊格式的字符串
    • 实际工作中,这个 JSON 字符串可能是自己手写的,也可能是来自网络接收的数据
  • 下面的一段 JSON 字符串,它可能是自己写的,也可能是服务端返回的
    • 它是压缩的格式,也就是没有换行和缩进,不方便判断格式是否正确
    • 可以通过 JSON 在线解析工具来校验这个 JSON 的格式是否正确
    {"name":"China","info":{"capital":"beijing","asian":true,"founded":1949},"provinces":
    [{"name":"hunan","capital":"changsha"},{"name":"hubei","capital": "huhan"}]}
    

在这里插入图片描述

1.4 Qt 中使用 JSON

1.4.1 JSON 相关的类

(1)QJsonObject

  • QJsonObject 封装了 JSON 中的对象,可以存储多个键值对
    • 其中,键为字符串类型,值为 QJsonValue 类型
  • 创建一个 QJsonObject 对象
    QJsonObject::QJsonObject();
    
  • 将键值对添加到 QJsonObject 对象中
    QJsonObject::iterator insert(const QString &key, const QJsonValue &value);
    
  • 获取 QJsonObject 对象中键值对的个数
    int QJsonObject::count() const;
    int QJsonObject::size() const;
    int QJsonObject::length() const;
    
  • 通过 key 得到 value
    QJsonValue QJsonObject::value(const QString &key) const;
    QJsonValue QJsonObject::operator[](const QString &key) const;
    
  • 检查 key 是否存在
    iterator QJsonObject::find(const QString &key);
    bool QJsonObject::contains(const QString &key) const;
    
  • 遍历 key
    QStringList QJsonObject::keys() const;
    

(2)QJsonArray

  • QJsonArray 封装了 Json 中的数组,数组中元素类型统一为 QJsonValue 类型
  • 创建一个 QJsonArray
    QJsonArray::QJsonArray();
    
  • 添加数组元素
    // 添加到头部和尾部
    void QJsonArray::append(const QJsonValue &value);
    void QJsonArray::prepend(const QJsonValue &value);
    
    // 插入到 i 的位置之前
    void QJsonArray::insert(int i, const QJsonValue &value);
    
    // 添加到头部和尾部
    void QJsonArray::push_back(const QJsonValue &value);
    void QJsonArray::push_front(const QJsonValue &value);
    
  • 获取 QJsonArray 中元素个数
    int QJsonArray::count() const;
    int QJsonArray::size() const;
    
  • 获取元素的值
    // 获取头部和尾部
    QJsonValue QJsonArray::first() const;
    QJsonValue QJsonArray::last() const;
    
    // 获取指定位置
    QJsonValue QJsonArray::at(int i) const;
    QJsonValueRef QJsonArray::operator[](int i);
    
  • 删除元素
    // 删除头部和尾部
    void QJsonArray::pop_back();
    void QJsonArray::pop_front();
    
    void QJsonArray::removeFirst();
    void QJsonArray::removeLast();
    
    // 删除指定位置
    void QJsonArray::removeAt(int i);
    QJsonValue QJsonArray::takeAt(int i);
    

(3)QJsonValue

  • 封装了 JSON 支持的六种数据类型

    QJsonValue::Bool      // 布尔类型
    QJsonValue::Double    // 浮点(含整型)类型
    QJsonValue::String    // 字符串类型
    QJsonValue::Array     // Json 数组类型
    QJsonValue::Object    // Json 对象类型
    QJsonValue::Null      // 空值类型
    
  • 可以通过以下方式构造 QJsonValue 对象

    // 字符串
    QJsonValue(const char *s);
    QJsonValue(QLatin1String s);
    QJsonValue(const QString &s);
    
    // 整型 and 浮点型
    QJsonValue(qint64 v);
    QJsonValue(int v);
    QJsonValue(double v);
    
    // 布尔类型
    QJsonValue(bool b);
    
    // Json 对象
    QJsonValue(const QJsonObject &o);
    
    // Json 数组
    QJsonValue(const QJsonArray &a);
    
    // 空值类型
    QJsonValue(QJsonValue::Type type = Null);
    
  • 判断一个 QJsonValue 对象内部封装数据类型

    // 是否是字符串类型
    bool isString() const;
    
    // 是否是浮点类型(整形也是通过该函数判断)
    bool isDouble const;
    
    // 是否是布尔类型
    bool isBool() const;
    
    // 是否是Json对象
    bool isObject() const;
    
    // 是否是 Json 数组
    bool isArray() const;
    
    // 是否是未定义类型(无法识别的类型)
    bool isUndefined() const;
    
    // 是否是空值类型
    bool isNull() const;
    
  • 数据类型之间的转换 API 函数

    // 转换为字符串类型
    QString toString() const;
    QString toString(const QString &defaultValue) const;
    
    // 转换为浮点类型
    double toDouble(double defaultValue = 0) const;
    
    // 转换为整形
    int toInt(int defaultValue = 0) const;
    
    // 转换为布尔类型
    bool toBool(bool defaultValue = false) const;
    
    // 转换为 Json 对象
    QJsonObject toObject() const;
    QJsonObject toObject(const QJsonObject &defaultValue) const;
    
    // 转换为 Json 数组
    QJsonArray toArray() const;
    QJsonArray toArray(const QJsonArray &defaultValue) const;
    

(3)QJsonDocument

  • 它封装了一个完整的 JSON 文档

    • 它可以从 UTF-8 编码的基于文本的表示,以及 Qt 本身的二进制格式读取和写入该文档
    • QJsonObject 和 QJsonArray 不能直接转换为字符类型,需通过 QJsonDocument 来完成二者的转换
  • QJsonObject/QJsonArray ==> 字符串

    // 1. 创建 QJsonDocument 对象
    // 以 QJsonObject 或 QJsonArray 为参数来创建 QJsonDocument 对象
    QJsonDocument::QJsonDocument(const QJsonObject &object);
    QJsonDocument::QJsonDocument(const QJsonArray &array);
    
    // 2. 将 QJsonDocument 对象中的数据进行序列化
    // 通过调用 toXXX() 方法就可得到文本格式或者二进制格式的 Json 字符串
    QByteArray QJsonDocument::toBinaryData() const;         // 二进制格式的 json 字符串
    QByteArray QJsonDocument::toJson(JsonFormat format = Indented) const;  // 文本格式
    
    // 3. 使用得到的字符串进行数据传输,或者保存到文件
    
  • 字符串 ==> QJsonObject/QJsonArray

    • 通常,通过网络接收或者读取磁盘文件,会得到一个 JSON 格式的字符审,之后可以按照如下步骤,解析出 JSON 字符串中的一个个字段
    // 1. 将 JSON 字符串转换为 QJsonDocument 对象
    [static] QJsonDocument QJsonDocument::fromBinaryData(const QByteArray &data,DataValidation validation = Validate);
    [static] QJsonDocument QJsonDocument::fromJson(const QByteArray &json, QJsonParseError *error = Q_NULLPTR);
    
    // 2. 将文档对象转换为 json 数组 / 对象
    // 2.1 判断文档对象中存储的数据是 JSON 数组还是 JSON 对象
    bool QJsonDocument::isArray() const;
    bool QJsonDocument::isObject() const;
    
    // 2.2 转换为 JSON 数组或 JSON 对象
    QJsonObject QJsonDocument::object() const;
    QJsonArray QJsonDocument::array() const;
    
    // 3. 调用 QJsonArray / QJsonObject 类提供的 API 获取存储在其中的数据
    
1.4.2 构建 JSON 字符串
  • 在网络传输时,通常是传输的 JSON 字符串,传输之前,首先要生成 JSON 字符串
    • 接下来使用 Qt 提供的工具类,来生成如下格式的 JSON 字符串
    {
        "name": "China",
        "info": {
            "capital": "beijing",
            "asian": true,
            "founded": 1949
        },
        "provinces": [{
            "name": "hunan",
            "capital": "changsha"
        }, {
            "name": "hubei",
            "capital": "wuhan"
        }]
    }
    
  • 代码实现
    #include <QCoreApplication>
    
    #include <QJsonObject>
    #include <QJsonArray>
    #include <QJsonDocument>
    
    #include <QFile>
    #include <QByteArray>
    #include <QDebug>
    #include <QString>
    
    void writeJson() {
        QJsonObject rootObj;
    
        // 1. 插入 name 字段
        rootObj.insert("name", "China");
    
        // 2. 插入 info 字段
        QJsonObject infoObj;
        infoObj.insert("capital", "beijing");
        infoObj.insert("asian", true);
        infoObj.insert("founded", 1949);
    
        rootObj.insert("info", infoObj);
    
        // 3. 插入 provinces 字段
        QJsonArray provinceArray;
    
        QJsonObject hunanObj;
        hunanObj.insert("name", "hunan");
        hunanObj.insert("capital", "changsha");
    
        QJsonObject hubeiObj;
        hubeiObj.insert("name", "hubei");
        hubeiObj.insert("capital", "wuhan");
    
        provinceArray.append(hunanObj);
        provinceArray.append(hubeiObj);
    
        rootObj.insert("provinces", provinceArray);
    
        // 4. 将 QJsonObject 对象 rootObj 转换为 Json 字符串
        QJsonDocument doc(rootObj);
        QByteArray json = doc.toJson();
    
        // 5.1 打印输出
        qDebug() << QString(json).toUtf8().data();
    
        // 5.2 将 json 字符串写入文件
        QFile file("d:\\china.json");
        file.open(QFile::WriteOnly);
        file.write(json);
        file.close();
    }
    
    int main(int argc, char *argv[]) {
        QCoreApplication a(argc, argv);
    
        writeJson();
    
        return a.exec();
    }
    
1.4.3 解析 JSON 字符串
  • 通常接收网络数据的格式是JSON 格式,在接收完毕之后,需要解析出其中的每一个字段,根据各个字段的值做相应的显示或者其他处理
#include <QCoreApplication>

#include <QJsonObject>
#include <QJsonArray>
#include <QJsonDocument>
#include <QJsonValue>

#include <QFile>
#include <QByteArray>
#include <QDebug>
#include <QString>
#include <QStringList>

void fromJson() {
    // 1. 读取文件
    QFile file("d:\\china.json");
    file.open(QFile::ReadOnly);
    QByteArray json = file.readAll();
    file.close();

    QJsonDocument doc = QJsonDocument::fromJson(json);
    if (!doc.isObject()) {
        qDebug() << "Not an object!";
        return;
    }

    // 2. 开始解析
    QJsonObject obj = doc.object();
    QStringList keys = obj.keys();
    for (int i = 0; i < keys.size(); i++) {
        // 获取 key-value 对
        QString key = keys[i];
        QJsonValue value = obj.value(key);

        if (value.isBool()) {
            qDebug() << key << ":" << value.toBool();
        } else if (value.isString()) {
            qDebug() << key << ":" << value.toString();
        } else if (value.isDouble()) {
            qDebug() << key << ":" << value.toInt();
        } else if (value.isObject()) {
            qDebug() << key << ":";

            QJsonObject infoObj = value.toObject();
            QString capital = infoObj["capital"].toString();
            bool asian = infoObj["asian"].toBool();
            int founded = infoObj["founded"].toInt();

            qDebug() << " " << "capital" << capital;
            qDebug() << " " << "asian" << asian;
            qDebug() << " " << "founded" << founded;
        } else if (value.isArray()) {
            qDebug() << key;
            QJsonArray provinceArray = value.toArray();

            for (int i = 0; i < provinceArray.size(); i++) {
                QJsonObject provinceObj = provinceArray[i].toObject();
                QString name = provinceObj["name"].toString();
                QString capital = provinceObj["capital"].toString();

                qDebug() << " " << "name" << ":" << name << ", capital" << ":" << capital;
            }
        }
    }
}

int main(int argc, char *argv[]) {
    QCoreApplication a(argc, argv);

    fromJson();

    return a.exec();
}
  • 控制台输出
    "info" :
      capital "beijing"
      asian true
      founded 1949
    "name" : "China"
    "provinces"
      name : "hunan" , capital : "changsha"
      name : "hubei" , capital : "wuhan"
    

2. HTTP 通信

2.1 HTTP 概述

HTTP:超文本传输协议 (HyperText Transfer Protocol),HTTP 是浏览器端 web 通信的基础

2.1.1 两种架构
  • B/S 架构:Browser/server,浏览器/服务器架构
    • B:浏览器,比如 Firefox、Internet Explorer、Google Chrome、Safari、Opera 等
    • S:服务器,比如 Apache、nginx 等
  • C/S 架构:client/server,客户端/服务器架构
    • B/S 架构相对于 C/S 架构,客户机上无需安装任何软件,使用浏览器即可访问服务器,因此,越来越多的 C/S 架构正被 B/S 架构所替代
2.1.2 基于请求响应的模式
  • HTTP 协议永远都是客户端发起请求,服务器做出响应
    • 也就是说,请求必定是先从客户端发起的,服务器端在没有接收到请求之前不会发送任何响应
    • 这就无法实现这样一种场景:服务端主动推送消息给客户端
2.1.3 无状态
  • 当浏览器第一次发送请求给服务器时,服务器做出了响应

  • 当浏览器第二次发送请求给服务器时,服务器同样可以做出响应,但服务器并不知道第二次的请求和第一次来自同一个浏览器

    • 也就是说,服务器不会记住你是谁,所以是无状态的
  • 而如果要使 HTTP 协议有状态,就可以使浏览器访问服务器时,加入 cookie,这样,只要你在请求时有了这个 cookie,服务器就能够通过 cookie 知道,你就是之前那个浏览器,这样,HTTP 协议就有状态了

2.1.4 请求保文

请求报文由四部分组成

  • 请求行 + 请求头(请求首部字段) + 空行 + 实体
  • 请求行

    • 请求方法:比如 GET、POST
    • 资源对象 (URL)
    • 协议名称和版本号 (HTTP/1.1)
      在这里插入图片描述
  • 请求头(请求首部字段)

    • 请求头用于告诉服务器该请求的一些信息,起到传递额外信息的目的
      在这里插入图片描述
  • 空行

    • 空行是为了区分请求头和请求实体
  • 请求实体

    • 请求实体即真正所需要传输的数据
2.1.5 响应保文

响应报文同样是由四部分组成

  • 状态行 + 响应头(响应报文首部) + 空行 + 消息体
  • 状态行

    • HTTP 版本
    • 状态码 (表示相应的结果)
    • 原因短语 (解释)
      在这里插入图片描述
  • 响应头(响应报文首部)

    • 和请求报文首部一样,响应报文首部同样是为了传递额外信息
      在这里插入图片描述
  • 空行

    • 同样是为了区别响应实体和响应首部
  • 响应实体

    • 真正存储响应信息的部分
2.1.6 请求方式
  • HTTP 常用的请求方式有很多中,最常用的是 GET 和 POST
  • 二者最主要的区别就是
    • GET 请求的参数位于 URL 中,会显示在地址栏上
    • POST 请求的参数位于 request body 请求体中

因此,GET 请求的安全性不如 POST 请求,并且 GET 请求的参数有长度限制,而 POST 没有

2.2 调试利器 Postman

  • HTTP 包含客户端和服务端,试想下面的两种情况(Postman 使用场景
    • 服务端开发完毕,而客户端还未完成开发,此时服务端开发人员能否对自己写的服务端程序进行测试呢?
    • 客户端开发人员访问服务端出错,比如无法访问服务端,有没有第三方的测试工具做进一步验证呢?
  • Postman 是一个接口测试工具,主要是用来模拟各种 HTTP 请求 (比如 GET 请求、POST 请求等),在做接口测试的时候,Postman 相当于客户端,它可模拟用户发起的各类 HTTP 请求,将请求数据发送至服务端,并获取对应的响应结果
2.2.1 安装
  • Postman 下载
2.2.2 发送请求
  • 这里以获取北京的天气为例
    • 获取北京天气的 URL 为:http://t.weather.itboy.net/api/weather/city/101010100
    • 其中,101010100 是北京的城市编码,是 9 位的

在这里插入图片描述

2.3 Qt 实现 HTTP 请求

2.3.1 创建 “网络访问管理” 对象
  • 首先需要创建一个 QNetworkAccessManager 对象,这是 Qt 中进行 HTTP 请求的开端
    mNetAccessManager = new QNetworkAccessManager(this);
    
2.3.2 关联信号槽
  • 在发送 HTTP 请求之前,先关联信号槽
    // 获取到数据之后
    connect(mNetAccessManager, &QNetworkAccessManager::finished, this, &MainWindow::onReplied);
    
2.3.3 发送请求
  • 根据请求的地址构建出一个 Qurl 对象,然后直接调用 QNetworkAccessManager 的 get 方法,即可发送一个 GET 请求
    Qurl ur1("http://t.weather.itboy.net/api/weather/city/101010100");
    mNetAccessManager->get(QNetworkRequest(url));
    
2.3.4 接收数据
  • 由于上面绑定了信号槽,服务器返回数据后,自动调用自定义的槽函数 onReplied
    • 如下是 onReplied 函数的标准写法,QNetworkReply 中封装了服务器返回的所有数据,包括响应头、响应的状态码、响应体等
    void MainWindow::onReplied(QNetworkReply *reply) {
        // 响应的状态码为200,表示请求成功
        int status_code = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();
    
        qDebug() << "operation:" << reply->operation();          // 请求方式
        qDebug() << "status code:" << status_code;             // 状态码
        qDebug() << "url:" << reply->url();                    // url
        qDebug() << "raw header:" << reply->rawHeaderList();   // header
    
        if (reply->error() != QNetworkReply::NoError || status_code != 200) {
            QMessageBox::warning(this, "提示", "请求数据失败!", QMessageBox::OK);
        } else {
            // 获取响应信息
            QByteArray reply_data = reply->readAll();
            QByteArray byteArray = QString(reply_data).toUtf8();
            qDebug() << "read all:" << byteArray.data();
    
            // parseJson()
        }
    
        reply->deleteLater();
    }
    

3. 详细代码实现

  • WeatherForecast

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/201709.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

使用影刀指令+python实现简单的长文本乱序加密

本文意在利用影刀指令python代码&#xff0c;实现一种较为简单的长文本加密和解密&#xff0c;流程结构分为两步&#xff1a; 加密原理–是把字符转为列表&#xff0c;利用列表random模块中的shuffle函数做随机乱序。解密原理–是利用了列表的索引追踪&#xff0c;先前创建字典…

VSCODE+QEMU+WSL调试RISCV代码(SBI、kernel)

前言 最近在对RISC-V架构比较感兴趣&#xff0c;正好手头有《RISC-V体系结构编程与实践》的书籍&#xff0c;就打算跟随笨叔将这块的知识学习起来&#xff0c;最开始当然是需要搭建一个基础的实验平台&#xff0c;本来笨叔是贴心的提供了VMare的环境&#xff0c;奈何天生叛逆的…

Ubuntu部署jmeter与ant

为了整合接口自动化的持续集成工具&#xff0c;我将jmeter与ant都部署在了Jenkins容器中&#xff0c;并配置了build.xml 一、ubuntu部署jdk 1&#xff1a;先下载jdk-8u74-linux-x64.tar.gz&#xff0c;上传到服务器&#xff0c;这里上传文件用到了ubuntu 下的 lrzsz。 ubunt…

文件基础知识

计算机中的流&#xff1a;在C语言中将通过输入/输出设备&#xff08;键盘、内存、显示器、网络等&#xff09;之间的数据传输抽象表述为“流”。 1、文本流和二进制流 在文本流中输入输出的数据是一系列的字符&#xff0c;可以被修改在二进制流中输入输出数据是一系列字节&am…

C++初阶(十三)vector

&#x1f4d8;北尘_&#xff1a;个人主页 &#x1f30e;个人专栏:《Linux操作系统》《经典算法试题 》《C》 《数据结构与算法》 ☀️走在路上&#xff0c;不忘来时的初心 文章目录 一、vector的介绍二、vector的模拟实现1、模拟实现2、测试结果 一、vector的介绍 vector的文…

基于YOLOv5的人群计数系统设计系统

欢迎大家点赞、收藏、关注、评论啦 &#xff0c;由于篇幅有限&#xff0c;只展示了部分核心代码。 文章目录 一项目简介系统概述系统功能核心技术系统架构系统优势 二、功能三、系统四. 总结  总结 一项目简介 基于YOLOv5的人群计数系统设计是一个非常有趣且具有挑战性的项目…

html5各行各业官网模板源码下载(1)

文章目录 1.来源2.源码模板2.1 HTML5白色简洁设计师网站模板 作者&#xff1a;xcLeigh 文章地址&#xff1a;https://blog.csdn.net/weixin_43151418/article/details/134682321 html5各行各业官网模板源码下载&#xff0c;这个主题覆盖各行业的html官网模板&#xff0c;效果模…

软件设计师——法律法规(一)

&#x1f4d1;前言 本文主要是【法律法规】——软件设计师法律法规的题目&#xff0c;如果有什么需要改进的地方还请大佬指出⛺️ &#x1f3ac;作者简介&#xff1a;大家好&#xff0c;我是听风与他&#x1f947; ☁️博客首页&#xff1a;CSDN主页听风与他 &#x1f304;每日…

【LeetCode刷题】数组篇1

&#x1f387;数组简单题Part &#x1f308; 开启LeetCode刷题之旅 &#x1f308; 文章目录 &#x1f387;数组简单题Part&#x1f370;1.两数之和&#x1f451;思路分析1.暴力法2.哈希表法 &#x1f370;26.删除有序数组中的重复项&#x1f451;思路分析1.双指针2.利用vector…

微信小程序上传报错TypeError: Failed to fetch

上传之后报message&#xff1a;TypeError: Failed to fetch这个错误。 关掉项目 > 选择项目的ide界面右上有个齿轮设置 > 代理

【面试】css预处理器之sass(scss)

目录 为什么引入css预处理器 可读性 嵌套&#xff1a;关系明朗 选择器 属性 伪类‘’ 变量&#xff1a;语义明确 默认变量&#xff1a;美元符号 $ 变量名:值 !default 全局变量&#xff1a;:global { $global-x: } 变量插值&#xff1a;#{} map键值对&#xff1a;$…

函数保留凸性的一些运算,限制为一条线

凸优化在学术研究中非常重要&#xff0c;经常遇到的问题是证明凸性。常规证明凸性的方式是二阶导数的黑塞矩阵为半正定&#xff0c;或者在一维函数时二阶导数大于等于零。但很多时候的数学模型并不那么常规、容易求导的&#xff0c;若能够知道一些保留凸性的运算&#xff0c;将…

Zemax光学设计——单透镜设计

单透镜系统参数&#xff1a; 入瞳直径&#xff1a;20mm F/#&#xff08;F数&#xff09;&#xff1a;10 全视场&#xff1a;10 波长&#xff1a;587nm 材料&#xff1a;BK7 优化方向&#xff1a;最佳均方根光斑直径 设计步骤 一、单透镜系统参数 步骤一&#xff1a;入…

红黑树的插入

一.红黑树的特征 红黑树是二叉搜索树红黑树分为内部结点和外部结点,将空指针视为外部结点,其它结点视为内部结点根结点和外部结点都是黑色从根结点到外部结点的路径上不能有连续的红结点从根结点到外部结点的路径上黑结点的数目相同从根结点到外部结点的最长路径的长度不超过最…

Spring Framework远程代码执行漏洞 CVE-2022-22965 漏洞复现

Spring Framework远程代码执行漏洞 CVE-2022-22965 漏洞复现和相关利用工具 名称: Spring Framework 远程命令执行漏洞 描述: Spring core是Spring系列产品中用来负责发现、创建并处理bean之间的关系的一个工具包&#xff0c;是一个包含Spring框架基本的核心工具包&#xff0…

爬虫代理技术与构建本地代理池的实践

爬虫中代理的使用&#xff1a; 什么是代理 代理服务器 代理服务器的作用 就是用来转发请求和响应 在爬虫中为何需要使用代理&#xff1f; 隐藏真实IP地址&#xff1a;当进行爬取时&#xff0c;爬虫程序会发送大量的请求到目标网站。如果每个请求都使用相同的IP地址&#xff…

深入Python元编程:了解声明与初始化定制元类

更多资料获取 &#x1f4da; 个人网站&#xff1a;ipengtao.com 简介 在Python中&#xff0c;元编程是指在运行时创建或定制类的编程。元类是Python中最强大的元编程工具之一&#xff0c;允许您控制类的创建过程。元类是类的类&#xff0c;它控制类的实例化&#xff0c;允许您…

【软件测试学习】—软件测试模型(二)

【软件测试学习】—软件测试模型&#xff08;二&#xff09; 我 | 在这里 &#x1f469;‍&#x1f9b0;&#x1f469;‍&#x1f9b0; 读书 | 长沙 ⭐计算机科学与技术 ⭐ 本科 【2024届】 &#x1f383;&#x1f383; 爱好 | 旅游、跑步、网易云、美食、摄影 &#x1f396;️…

修复 MyBatis 中空值引起的 SQL 语法错误

修复 MyBatis 中空值引起的 SQL 语法错误 背景 最近在查看别人的项目代码时&#xff0c;遇到了一个问题&#xff1a;数据库中的数据为空。在调试过程中&#xff0c;发现问题出现在调用 MyBatis 中的方法&#xff1a;listByIds(Collection<? extends Serializable> idL…

QML Column Row 属性 pyside6

在 QML 中&#xff0c;Column 和 Row 是常用的布局元素&#xff0c;用于水平&#xff08;Row&#xff09;和垂直&#xff08;Column&#xff09;排列它们的子元素。以下是这两个元素的主要属性列表&#xff1a; Column 属性 spacing: 子元素之间的垂直间隔。width 和 height:…