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 truefounded 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();                    // urlqDebug() << "raw header:" << reply->rawHeaderList();   // headerif (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.mzph.cn/news/184666.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【UE】剔除环境颜色

效果 步骤 1. 新建一个空白项目&#xff0c;勾选光线追踪选项 2. 新建一个Basic关卡 3. 添加初学者内容包到内容浏览器 4. 新建一个材质“M_Red” 打开“M_Red”&#xff0c;设置基础颜色为红色 在场景中随便布置一些物品&#xff0c;然后给其中的一个球体设置材质为“M_Red”…

Oracle--索引

文章目录 一、索引是什么?二、索引的原理三、索引的特征四、创建索引的方式五、怎么确认索引六、案列七、复合索引 一、索引是什么? 索引&#xff08;INDEX&#xff09;是数据库中用于提高查询效率的一种数据结构。它可以加速数据库表的数据查找、过滤和排序等操作。索引是一…

python 协程

1. 协程 协程&#xff0c;又称微线程&#xff0c;纤程。英文名Coroutine。 https://www.cnblogs.com/coder-qi/p/10163416.html 协程不是计算机提供的&#xff0c;是人为创造的上下文切换技术&#xff0c;也可以被称为微线程。简而言之 其实就是在一个线程中实现代码块相互切…

Lesson 08 string类 (中)

C&#xff1a;渴望力量吗&#xff0c;少年&#xff1f; 文章目录 二、string类的介绍与使用2. 使用&#xff08;5&#xff09;string类对象的修改操作 三、拷贝1. 引入2. 浅拷贝3. 深拷贝 总结 二、string类的介绍与使用 2. 使用 &#xff08;5&#xff09;string类对象的修改…

Scrum敏捷开发流程及支撑工具

Scrum是一种敏捷开发框架&#xff0c;用于管理复杂的项目。以下这些步骤构成了Scrum敏捷开发流程的核心。通过不断迭代、灵活应对变化和持续反馈&#xff0c;Scrum框架帮助团队快速交付高质量的产品。 以下是Scrum敏捷开发流程的基本步骤&#xff1a; 产品Backlog创建&#xf…

微服务--06--Sentinel 限流、熔断

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 1.微服务保护雪崩问题服务保护方案1.1.请求限流1.2.线程隔离1.3.服务熔断 2.Sentinel2.1.介绍和安装官方网站&#xff1a;[https://sentinelguard.io/zh-cn/](https…

打造高效项目团队,离不开有效的反馈机制

为了确保项目高效交付&#xff0c;项目经理需要在管理过程中及时发现问题并解决&#xff0c;所以80%的时间都在进行沟通以及各种项目汇报。但项目经理往往会陷入低频沟通、无意义汇报的困局&#xff0c;进而导致四处救火、项目各种延误、团队的工作效率低下。例如&#xff1a; …

Leetcode2336 无限集中的最小数字

题目&#xff1a; 现有一个包含所有正整数的集合 [1, 2, 3, 4, 5, ...] 。 实现 SmallestInfiniteSet 类&#xff1a; SmallestInfiniteSet() 初始化 SmallestInfiniteSet 对象以包含 所有 正整数。int popSmallest() 移除 并返回该无限集中的最小整数。void addBack(int nu…

VERAS:AI驱动的Revit可视化渲染插件

Veras 是一款基于生成式AI 的可视化工具&#xff0c;可以使用自然语言生成3D渲染效果&#xff0c;兼容Revit、Rhino 和 SketchUp。Veras for Revit工具使用 Revit 模型内部的 3D 视图。 NSDT工具推荐&#xff1a; Three.js AI纹理开发包 - YOLO合成数据生成器 - GLTF/GLB在线编…

如何把ipa文件(iOS安装包)安装到iPhone手机上? 附方法汇总

文章目录 概要整体架构流程技术名词解释技术细节小结 概要 技术细节 目录 Appuploader 常见错误及解决方法 苹果APP安装包ipa如何安装在手机上&#xff1f;很多人不知道怎么把ipa文件安装到手机上&#xff0c;这里就整理了苹果APP安装到iOS设备上的方式&#xff0c;仅供参考 苹…

说说你对slot的理解?slot使用场景有哪些?

面试官&#xff1a;说说你对slot的理解&#xff1f;slot使用场景有哪些&#xff1f; 一、slot是什么 在HTML中 slot 元素 &#xff0c;作为 Web Components 技术套件的一部分&#xff0c;是Web组件内的一个占位符 该占位符可以在后期使用自己的标记语言填充 举个栗子 <t…

安科瑞智能照明系统在福建二建大厦项目上的应用

【摘要】&#xff1a;智能化已经成为当今建筑发展的主流技术、涵盖从空调系统、消防系统到安全防范系统以及完善的计算机网络和通信系统。但是长期以来、智能照明在国内一直被忽视、大多数建筑物仍然沿用传统的照明控制方式、部分智能大厦采用楼宇自控&#xff08;BA&#xff0…

vue2全局混入正确使用场景和错误场景示例

全局混入在 Vue.js 中的使用场景需要谨慎考虑&#xff0c;因为它会影响所有组件。以下是一些正确和错误的使用场景的例子&#xff1a; 正确的使用场景&#xff1a; 全局工具方法&#xff1a; // 正确的使用场景 Vue.mixin({methods: {$formatDate: function (date) {// 格式化…

算法面试题--树与对象数组的转化

1. Array -> Tree var arr [{ id: 12, parentId: 1, name: "朝阳区" },{ id: 241, parentId: 24, name: "田林街道" },{ id: 31, parentId: 3, name: "广州市" },{ id: 13, parentId: 1, name: "昌平区" },{ id: 2421, parentId:…

曲面拼接oled屏幕为何受到企业展览青睐

曲面拼接OLED屏幕受到企业展览青睐的原因主要有以下几点&#xff1a; 创新的技术&#xff1a;曲面拼接OLED屏幕采用先进的OLED技术&#xff0c;具有自发光原理&#xff0c;可以实现真正的黑色和高对比度&#xff0c;呈现出生动的图像。其每个像素都能独立发光&#xff0c;没有背…

Windows系统下使用PHPCS+PHPMD+GIT钩子

前言 使用PHPCSGIT钩子保障团队开发中代码风格一致性实践 使用PHPMD提高代码质量与可读性 0.介绍 PHP_CodeSniffer php代码嗅探器 包含phpcs(php code standard 代码标准) phpcbf(php code beautify fix 代码美化修复) 是一个代码风格检测工具,着重代码规范 它包含两类脚本…

有时出厂重置BIOS是解决电脑问题和保持其最佳性能的好办法,主要有两种方法

​BIOS是计算机开机时启动的第一个程序&#xff0c;它有助于执行一些基本的计算机操作&#xff0c;并管理计算机和安装在计算机上的操作系统之间的命令。与任何其他程序一样&#xff0c;如果在启动计算机时遇到问题或在计算机中添加了新硬件&#xff0c;则可能需要将BIOS重置为…

「幻醒蓝」可视化主题套件|融合天空的清澈与海洋的深邃

现如今&#xff0c;数据可视化已成为信息传递的重要手段之一。在这样一个信息爆炸的时代&#xff0c;向人们传达正确的信息显得尤为重要。为此&#xff0c;可视化主题套件应运而生&#xff0c;提供了一种多样化的、可视化的方式来展示数据。不同的主题套件能够适应不同的信息传…

免费的电脑AI写作工具-5款好用的智能AI写作软件

随着人工智能&#xff08;AI&#xff09;技术的不断进步&#xff0c;电脑AI写作已经成为现代写作领域的一项不可或缺的工具。通过深度学习和自然语言处理的融合&#xff0c;AI写作软件得以模拟人类的创造性和表达能力&#xff0c;为我们提供了快速、高效地生成优质文字内容的可…

15.spring源码解析-invokeBeanFactoryPostProcessors

BeanFactoryPostProcessor接口允许我们在bean正是初始化之前改变其值。此接口只有一个方法: void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory);有两种方式可以向Spring添加此对象: 通过代码的方式: context.addBeanFactoryPostProcessor 通过xml…