当前位置: 首页 > news >正文

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

相关文章:

Qt 天气预报项目

参考引用 QT开发专题-天气预报 1. JSON 数据格式 1.1 什么是 JSON JSON (JavaScript Object Notation)&#xff0c;中文名 JS 对象表示法&#xff0c;因为它和 JS 中对象的写法很类似 通常说的 JSON&#xff0c;其实就是 JSON 字符串&#xff0c;本质上是一种特殊格式的字符串…...

新知识-Tuple元组的使用

文章目录 前言一、tuple元组是什么&#xff1f;二、解决方法总结 前言 这次碰到一个需求&#xff0c;大致需要把表A中的字段1和字段2作为共同的表去查表B&#xff0c;并且一次性需要查多条&#xff0c;一开始是想的是根据字段1和字段2去查然后循环多次&#xff0c;但是这样反复…...

“此应用专为旧版android打造,因此可能无法运行”,问题解决方案

当用户在Android P系统上打开某些应用程序时&#xff0c;可能会弹出一个对话框&#xff0c;提示内容为&#xff1a;“此应用专为旧版Android打造&#xff0c;可能无法正常运行。请尝试检查更新或与开发者联系”。 随着Android平台的发展&#xff0c;每个新版本通常都会引入新的…...

【Leetcode题单】(01 数组篇)刷题关键点总结03【数组的改变、移动】

【Leetcode题单】&#xff08;01 数组篇&#xff09;刷题关键点总结03【数组的改变、移动】&#xff08;3题&#xff09; 数组的改变、移动453. 最小操作次数使数组元素相等 Medium665. 非递减数列 Medium283. 移动零 Easy 大家好&#xff0c;这里是新开的LeetCode刷题系列&…...

Lag-Llama:基于 LlaMa 的单变量时序预测基础模型

文章构建了一个通用单变量概率时间预测模型 Lag-Llama&#xff0c;在来自Monash Time Series库中的大量时序数据上进行了训练&#xff0c;并表现出良好的零样本预测能力。在介绍Lag-Llama之前&#xff0c;这里简单说明什么是概率时间预测模型。概率预测问题是指基于历史窗口内的…...

vue3 :deep() 深度选择器不生效

vue3 :deep() 深度选择器不生效 问题出在根节点上&#xff0c;如果没有这个根节点&#xff0c;那么:deep()不起作用&#xff0c;我把根节点加上&#xff0c;:deep()样式就生效了。在组件外加个 就生效了 参考&#xff1a; 添加链接描述...

从零构建属于自己的GPT系列1:数据预处理(文本数据预处理、文本数据tokenizer、逐行代码解读)

&#x1f6a9;&#x1f6a9;&#x1f6a9;Hugging Face 实战系列 总目录 有任何问题欢迎在下面留言 本篇文章的代码运行界面均在PyCharm中进行 本篇文章配套的代码资源已经上传 从零构建属于自己的GPT系列1&#xff1a;文本数据预处理 从零构建属于自己的GPT系列2&#xff1a;语…...

c++中函数的引用

函数中的引用 引用可以作为函数的形参 不能返回局部变量的引用 #include<iostream> #include<stdlib.h> using namespace std; //形参是引用 void swap(int *x, int *y)//*x *y表示对x y取地址 { int tmp *x; *x *y; *y tmp; } void test01() { …...

IDA常用操作、快捷键总结以及使用技巧

先贴一张官方的图&#xff0c;然后我再总结一下&#xff0c;用的频率比较高的会做一些简单标注 快捷键 F系列【主要是调试状态的处理】 F2 添加/删除断点F4 运行到光标所在位置F5 反汇编F7 单步步入F8 单步跳过F9 持续运行直到输入/断点/结束 shift系列【主要是调出对应的页…...

Kibana使用指南

使用介绍主要特点应用场景数据可视化还有哪些类型安装步骤安装配置参数Elasticsearch配置参数注意事项 使用介绍 Kibana是一个开源的分析与可视化平台&#xff0c;设计出来用于和Elasticsearch一起使用的。可以用Kibana搜索、查看、交互存放在Elasticsearch索引里的数据&#…...

wvp如果确认音频udp端口开放成功

用到工具 在服务器上开启端口监听 选中udp server&#xff0c;点击创建按钮 设置服务器监听端口 在客户端连接服务器端口 选中udp客户端&#xff0c;点击创建 输入服务器地址 远程端口和本地端口&#xff0c;本地端口只要没被占用都可以使用 &#xff0c;点击确认 发送数据 …...

C#文件夹基本操作(判断文件夹是否存在、创建文件夹、移动文件夹、删除文件夹以及遍历文件夹中的文件)

目录 一、判断文件夹是否存在 1.Directory类的Exists()方法 2. DirectoryInfo类的Exists属性 二、创建文件夹 1. Directory类的CreateDirectory()方法 2.DirectoryInfo类的Create()方法 三、移动文件夹 1. Directory类的Move()方法 2.DirectoryInfo类的MoveT…...

python 交互模式和命令行模式的问题

python 模式的冲突 unexpected character after line continuation character 理论上 ide里&#xff0c;输入 python 文件路径\文件.py 就可以执行 但是有时候却报错 unexpected character after line continuation character 出现上述错误的原因是没有退出解释器&#x…...

计算机网络——数据链路层

目录 一、数据链路层的基本概念 &#xff08;一&#xff09;数据链路层的概念 &#xff08;二&#xff09;帧 &#xff08;三&#xff09;数据链路层分为哪两个部分 &#xff08;1&#xff09;LLC&#xff08;逻辑控制访问&#xff09; &#xff08;2&#xff09;MAC&…...

【限时免费】20天拿下华为OD笔试之【哈希集合】2023B-明明的随机数【欧弟算法】全网注释最详细分类最全的华为OD真题题解

文章目录 题目描述与示例题目描述输入描述输出描述&#xff1a;示例 1输入输出说明 解题思路代码PythonJavaC时空复杂度 华为OD算法/大厂面试高频题算法练习冲刺训练 题目描述与示例 题目描述 明明生成了N 个 1 至 500 之间的随机整数。请你删去其中重复的数字&#xff0c;即…...

播放器开发(五):视频帧处理并用SDL渲染播放

目录 学习课题&#xff1a;逐步构建开发播放器【QT5 FFmpeg6 SDL2】 步骤 VideoOutPut模块 1、初始化【分配缓存、读取信息】 2、开始线程工作【从队列读帧->缩放->发送渲染信号到窗口】 VideoWidget自定义Widget类 1、定义内部变量 2、如果使用SDL&#xff0c;需要进…...

Spring MVC数据绑定的几种方法(一)

这篇文章包含spring mvc的默认数据类型绑定和简单数据类型绑定。内容来自实验。 准备&#xff1a; &#xff08;1&#xff09;在IDEA环境中从archetye创建webapp类型的maven项目exp6。 &#xff08;2&#xff09;在src\main目录下创建并标注java源代码文件夹和resources资源文…...

CSP-坐标变换(其二)

问题描述 对于平面直角坐标系上的坐标 (x,y)&#xff0c;小 P 定义了如下两种操作&#xff1a; 拉伸 k 倍&#xff1a;横坐标 x 变为 kx&#xff0c;纵坐标 y 变为 ky&#xff1b; 旋转 θ&#xff1a;将坐标 (x,y) 绕坐标原点 (0,0) 逆时针旋转 θ 弧度&#xff08;0≤θ<…...

docker 安装jekins

echo Asia/Shanghai >/etc/timezone&#xff0c;容器中操作报错&#xff1a;docker容器中 Permission denied 使用该-u选项时&#xff0c;可以使用root用户(ID 0)&#xff0c;而不是用默认用户登录docker容器 docker exec -u 0 -it f8a2b3d91455 /bin/bash 或者&#xff…...

ChatGPT 问世一周年之际,开源大模型能否迎头赶上?

就在11月30日&#xff0c;ChatGPT 迎来了它的问世一周年&#xff0c;这个来自 OpenAI 的强大AI在过去一年里取得了巨大的发展&#xff0c;迅速吸引各个领域的用户群体。 我们首先回忆一下 OpenAI和ChatGPT这一年的大事记&#xff08;表格由ChatGPT辅助生成&#xff09;&#x…...

vue3 字体颜色设置的多种方式

在Vue 3中设置字体颜色可以通过多种方式实现&#xff0c;这取决于你是想在组件内部直接设置&#xff0c;还是在CSS/SCSS/LESS等样式文件中定义。以下是几种常见的方法&#xff1a; 1. 内联样式 你可以直接在模板中使用style绑定来设置字体颜色。 <template><div :s…...

镜像里切换为普通用户

如果你登录远程虚拟机默认就是 root 用户&#xff0c;但你不希望用 root 权限运行 ns-3&#xff08;这是对的&#xff0c;ns3 工具会拒绝 root&#xff09;&#xff0c;你可以按以下方法创建一个 非 root 用户账号 并切换到它运行 ns-3。 一次性解决方案&#xff1a;创建非 roo…...

DIY|Mac 搭建 ESP-IDF 开发环境及编译小智 AI

前一阵子在百度 AI 开发者大会上&#xff0c;看到基于小智 AI DIY 玩具的演示&#xff0c;感觉有点意思&#xff0c;想着自己也来试试。 如果只是想烧录现成的固件&#xff0c;乐鑫官方除了提供了 Windows 版本的 Flash 下载工具 之外&#xff0c;还提供了基于网页版的 ESP LA…...

04-初识css

一、css样式引入 1.1.内部样式 <div style"width: 100px;"></div>1.2.外部样式 1.2.1.外部样式1 <style>.aa {width: 100px;} </style> <div class"aa"></div>1.2.2.外部样式2 <!-- rel内表面引入的是style样…...

Spring AI 入门:Java 开发者的生成式 AI 实践之路

一、Spring AI 简介 在人工智能技术快速迭代的今天&#xff0c;Spring AI 作为 Spring 生态系统的新生力量&#xff0c;正在成为 Java 开发者拥抱生成式 AI 的最佳选择。该框架通过模块化设计实现了与主流 AI 服务&#xff08;如 OpenAI、Anthropic&#xff09;的无缝对接&…...

涂鸦T5AI手搓语音、emoji、otto机器人从入门到实战

“&#x1f916;手搓TuyaAI语音指令 &#x1f60d;秒变表情包大师&#xff0c;让萌系Otto机器人&#x1f525;玩出智能新花样&#xff01;开整&#xff01;” &#x1f916; Otto机器人 → 直接点明主体 手搓TuyaAI语音 → 强调 自主编程/自定义 语音控制&#xff08;TuyaAI…...

成都鼎讯硬核科技!雷达目标与干扰模拟器,以卓越性能制胜电磁频谱战

在现代战争中&#xff0c;电磁频谱已成为继陆、海、空、天之后的 “第五维战场”&#xff0c;雷达作为电磁频谱领域的关键装备&#xff0c;其干扰与抗干扰能力的较量&#xff0c;直接影响着战争的胜负走向。由成都鼎讯科技匠心打造的雷达目标与干扰模拟器&#xff0c;凭借数字射…...

OPENCV形态学基础之二腐蚀

一.腐蚀的原理 (图1) 数学表达式&#xff1a;dst(x,y) erode(src(x,y)) min(x,y)src(xx,yy) 腐蚀也是图像形态学的基本功能之一&#xff0c;腐蚀跟膨胀属于反向操作&#xff0c;膨胀是把图像图像变大&#xff0c;而腐蚀就是把图像变小。腐蚀后的图像变小变暗淡。 腐蚀…...

Linux C语言网络编程详细入门教程:如何一步步实现TCP服务端与客户端通信

文章目录 Linux C语言网络编程详细入门教程&#xff1a;如何一步步实现TCP服务端与客户端通信前言一、网络通信基础概念二、服务端与客户端的完整流程图解三、每一步的详细讲解和代码示例1. 创建Socket&#xff08;服务端和客户端都要&#xff09;2. 绑定本地地址和端口&#x…...

sipsak:SIP瑞士军刀!全参数详细教程!Kali Linux教程!

简介 sipsak 是一个面向会话初始协议 (SIP) 应用程序开发人员和管理员的小型命令行工具。它可以用于对 SIP 应用程序和设备进行一些简单的测试。 sipsak 是一款 SIP 压力和诊断实用程序。它通过 sip-uri 向服务器发送 SIP 请求&#xff0c;并检查收到的响应。它以以下模式之一…...