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),中文名 JS 对象表示法,因为它和 JS 中对象的写法很类似 通常说的 JSON,其实就是 JSON 字符串,本质上是一种特殊格式的字符串…...
新知识-Tuple元组的使用
文章目录 前言一、tuple元组是什么?二、解决方法总结 前言 这次碰到一个需求,大致需要把表A中的字段1和字段2作为共同的表去查表B,并且一次性需要查多条,一开始是想的是根据字段1和字段2去查然后循环多次,但是这样反复…...
“此应用专为旧版android打造,因此可能无法运行”,问题解决方案
当用户在Android P系统上打开某些应用程序时,可能会弹出一个对话框,提示内容为:“此应用专为旧版Android打造,可能无法正常运行。请尝试检查更新或与开发者联系”。 随着Android平台的发展,每个新版本通常都会引入新的…...
【Leetcode题单】(01 数组篇)刷题关键点总结03【数组的改变、移动】
【Leetcode题单】(01 数组篇)刷题关键点总结03【数组的改变、移动】(3题) 数组的改变、移动453. 最小操作次数使数组元素相等 Medium665. 非递减数列 Medium283. 移动零 Easy 大家好,这里是新开的LeetCode刷题系列&…...
Lag-Llama:基于 LlaMa 的单变量时序预测基础模型
文章构建了一个通用单变量概率时间预测模型 Lag-Llama,在来自Monash Time Series库中的大量时序数据上进行了训练,并表现出良好的零样本预测能力。在介绍Lag-Llama之前,这里简单说明什么是概率时间预测模型。概率预测问题是指基于历史窗口内的…...
vue3 :deep() 深度选择器不生效
vue3 :deep() 深度选择器不生效 问题出在根节点上,如果没有这个根节点,那么:deep()不起作用,我把根节点加上,:deep()样式就生效了。在组件外加个 就生效了 参考: 添加链接描述...
从零构建属于自己的GPT系列1:数据预处理(文本数据预处理、文本数据tokenizer、逐行代码解读)
🚩🚩🚩Hugging Face 实战系列 总目录 有任何问题欢迎在下面留言 本篇文章的代码运行界面均在PyCharm中进行 本篇文章配套的代码资源已经上传 从零构建属于自己的GPT系列1:文本数据预处理 从零构建属于自己的GPT系列2:语…...
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常用操作、快捷键总结以及使用技巧
先贴一张官方的图,然后我再总结一下,用的频率比较高的会做一些简单标注 快捷键 F系列【主要是调试状态的处理】 F2 添加/删除断点F4 运行到光标所在位置F5 反汇编F7 单步步入F8 单步跳过F9 持续运行直到输入/断点/结束 shift系列【主要是调出对应的页…...
Kibana使用指南
使用介绍主要特点应用场景数据可视化还有哪些类型安装步骤安装配置参数Elasticsearch配置参数注意事项 使用介绍 Kibana是一个开源的分析与可视化平台,设计出来用于和Elasticsearch一起使用的。可以用Kibana搜索、查看、交互存放在Elasticsearch索引里的数据&#…...
wvp如果确认音频udp端口开放成功
用到工具 在服务器上开启端口监听 选中udp server,点击创建按钮 设置服务器监听端口 在客户端连接服务器端口 选中udp客户端,点击创建 输入服务器地址 远程端口和本地端口,本地端口只要没被占用都可以使用 ,点击确认 发送数据 …...
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里,输入 python 文件路径\文件.py 就可以执行 但是有时候却报错 unexpected character after line continuation character 出现上述错误的原因是没有退出解释器&#x…...
计算机网络——数据链路层
目录 一、数据链路层的基本概念 (一)数据链路层的概念 (二)帧 (三)数据链路层分为哪两个部分 (1)LLC(逻辑控制访问) (2)MAC&…...
【限时免费】20天拿下华为OD笔试之【哈希集合】2023B-明明的随机数【欧弟算法】全网注释最详细分类最全的华为OD真题题解
文章目录 题目描述与示例题目描述输入描述输出描述:示例 1输入输出说明 解题思路代码PythonJavaC时空复杂度 华为OD算法/大厂面试高频题算法练习冲刺训练 题目描述与示例 题目描述 明明生成了N 个 1 至 500 之间的随机整数。请你删去其中重复的数字,即…...
播放器开发(五):视频帧处理并用SDL渲染播放
目录 学习课题:逐步构建开发播放器【QT5 FFmpeg6 SDL2】 步骤 VideoOutPut模块 1、初始化【分配缓存、读取信息】 2、开始线程工作【从队列读帧->缩放->发送渲染信号到窗口】 VideoWidget自定义Widget类 1、定义内部变量 2、如果使用SDL,需要进…...
Spring MVC数据绑定的几种方法(一)
这篇文章包含spring mvc的默认数据类型绑定和简单数据类型绑定。内容来自实验。 准备: (1)在IDEA环境中从archetye创建webapp类型的maven项目exp6。 (2)在src\main目录下创建并标注java源代码文件夹和resources资源文…...
CSP-坐标变换(其二)
问题描述 对于平面直角坐标系上的坐标 (x,y),小 P 定义了如下两种操作: 拉伸 k 倍:横坐标 x 变为 kx,纵坐标 y 变为 ky; 旋转 θ:将坐标 (x,y) 绕坐标原点 (0,0) 逆时针旋转 θ 弧度(0≤θ<…...
docker 安装jekins
echo Asia/Shanghai >/etc/timezone,容器中操作报错:docker容器中 Permission denied 使用该-u选项时,可以使用root用户(ID 0),而不是用默认用户登录docker容器 docker exec -u 0 -it f8a2b3d91455 /bin/bash 或者ÿ…...
ChatGPT 问世一周年之际,开源大模型能否迎头赶上?
就在11月30日,ChatGPT 迎来了它的问世一周年,这个来自 OpenAI 的强大AI在过去一年里取得了巨大的发展,迅速吸引各个领域的用户群体。 我们首先回忆一下 OpenAI和ChatGPT这一年的大事记(表格由ChatGPT辅助生成)&#x…...
【网络】每天掌握一个Linux命令 - iftop
在Linux系统中,iftop是网络管理的得力助手,能实时监控网络流量、连接情况等,帮助排查网络异常。接下来从多方面详细介绍它。 目录 【网络】每天掌握一个Linux命令 - iftop工具概述安装方式核心功能基础用法进阶操作实战案例面试题场景生产场景…...
【Python】 -- 趣味代码 - 小恐龙游戏
文章目录 文章目录 00 小恐龙游戏程序设计框架代码结构和功能游戏流程总结01 小恐龙游戏程序设计02 百度网盘地址00 小恐龙游戏程序设计框架 这段代码是一个基于 Pygame 的简易跑酷游戏的完整实现,玩家控制一个角色(龙)躲避障碍物(仙人掌和乌鸦)。以下是代码的详细介绍:…...
C++实现分布式网络通信框架RPC(3)--rpc调用端
目录 一、前言 二、UserServiceRpc_Stub 三、 CallMethod方法的重写 头文件 实现 四、rpc调用端的调用 实现 五、 google::protobuf::RpcController *controller 头文件 实现 六、总结 一、前言 在前边的文章中,我们已经大致实现了rpc服务端的各项功能代…...
安宝特方案丨XRSOP人员作业标准化管理平台:AR智慧点检验收套件
在选煤厂、化工厂、钢铁厂等过程生产型企业,其生产设备的运行效率和非计划停机对工业制造效益有较大影响。 随着企业自动化和智能化建设的推进,需提前预防假检、错检、漏检,推动智慧生产运维系统数据的流动和现场赋能应用。同时,…...
基于uniapp+WebSocket实现聊天对话、消息监听、消息推送、聊天室等功能,多端兼容
基于 UniApp + WebSocket实现多端兼容的实时通讯系统,涵盖WebSocket连接建立、消息收发机制、多端兼容性配置、消息实时监听等功能,适配微信小程序、H5、Android、iOS等终端 目录 技术选型分析WebSocket协议优势UniApp跨平台特性WebSocket 基础实现连接管理消息收发连接…...
【机器视觉】单目测距——运动结构恢复
ps:图是随便找的,为了凑个封面 前言 在前面对光流法进行进一步改进,希望将2D光流推广至3D场景流时,发现2D转3D过程中存在尺度歧义问题,需要补全摄像头拍摄图像中缺失的深度信息,否则解空间不收敛…...
基于Uniapp开发HarmonyOS 5.0旅游应用技术实践
一、技术选型背景 1.跨平台优势 Uniapp采用Vue.js框架,支持"一次开发,多端部署",可同步生成HarmonyOS、iOS、Android等多平台应用。 2.鸿蒙特性融合 HarmonyOS 5.0的分布式能力与原子化服务,为旅游应用带来…...
数据链路层的主要功能是什么
数据链路层(OSI模型第2层)的核心功能是在相邻网络节点(如交换机、主机)间提供可靠的数据帧传输服务,主要职责包括: 🔑 核心功能详解: 帧封装与解封装 封装: 将网络层下发…...
【HarmonyOS 5 开发速记】如何获取用户信息(头像/昵称/手机号)
1.获取 authorizationCode: 2.利用 authorizationCode 获取 accessToken:文档中心 3.获取手机:文档中心 4.获取昵称头像:文档中心 首先创建 request 若要获取手机号,scope必填 phone,permissions 必填 …...
项目部署到Linux上时遇到的错误(Redis,MySQL,无法正确连接,地址占用问题)
Redis无法正确连接 在运行jar包时出现了这样的错误 查询得知问题核心在于Redis连接失败,具体原因是客户端发送了密码认证请求,但Redis服务器未设置密码 1.为Redis设置密码(匹配客户端配置) 步骤: 1).修…...
