Qt——天气预报项目
1.窗口1:使用水平布局,内包含俩个QLabel类和一个QLineEdit类这里可以设置LineEdit中的提示文字 2.窗口2:使用栅格布局,这个天气图标组件的大小需限制一下 3.窗口3:里面包含一个子窗口,设置子窗口背景样式为橘色子窗口中的组件先垂直布局,后水平布局。最后整体再来一个栅格布局4.窗口4:里面包含6个子窗口。子窗口0401、0402、0406都需要进行栅格布局子窗口0401和04
一.ui界面的设计流程
1.窗口1:使用水平布局,内包含俩个QLabel类和一个QLineEdit类


这里可以设置LineEdit中的提示文字
![]()
2.窗口2:使用栅格布局,这个天气图标组件的大小需限制一下


3.窗口3:里面包含一个子窗口,设置子窗口背景样式为橘色
子窗口中的组件先垂直布局,后水平布局。最后整体再来一个栅格布局


4.窗口4:里面包含6个子窗口。子窗口0401、0402、0406都需要进行栅格布局
子窗口0401和0406中的组件是由俩个QLabel类拼接在一起的。

5.最后给4个窗口整体进行垂直布局即可
二.功能实现逻辑
2.1 如何实现单击右键时,弹出菜单,供用户选择是否要退出的功能?
解决方法:重写鼠标点击事件,以及绑定信号与槽。 当用户单击右键时候,在点击位置处显示出该菜单。当用户选择菜单后,会发出triggered信号,调用槽函数即可。
构造函数中先初始化菜单类
myMenu = new QMenu(this); //创建一个菜单加"Quit"和"not Quit"动作
QAction *QuitAction = new QAction("Quit", myMenu);
QAction *notQuitAction = new QAction("Not Quit", myMenu);
myMenu->addAction(QuitAction); //往菜单中添加组件
myMenu->addAction(notQuitAction);
connect(myMenu, &QMenu::triggered, this, [=](QAction *action){ //当用户点击这些动作时,会发出triggered信号
if (action->text() == "Quit") {
this->close();
} else if (action->text() == "Not Quit") {
return;
}
});
重写鼠标点击事件
void Widget::mousePressEvent(QMouseEvent *event)
{
if(event->button() == Qt::RightButton){ //当检测到鼠标右键按下时,在当前点击位置弹出菜单
myMenu->exec(QCursor::pos());
}
QWidget::mousePressEvent(event);
}
2.2 如何实现用户鼠标左键拖拽窗口移动功能?
解决方法:重写鼠标点击事件和鼠标移动事件。
void Widget::mousePressEvent(QMouseEvent *event)
{
if(event->button() == Qt::RightButton){ //当检测到鼠标右键按下时,在当前点击位置弹出菜单
myMenu->exec(QCursor::pos());
}
if(event->button() == Qt::LeftButton){
mOffset = event->globalPos() - this->pos(); //偏移值等于鼠标当前位置减去窗口当前的位置
}
QWidget::mousePressEvent(event);
}
void Widget::mouseMoveEvent(QMouseEvent *event)
{
//鼠标当前位置减去偏移值等于新的窗口的左顶点坐标
this->move(event->globalPos() - mOffset);
}
2.3 如何获取天气数据?
解决方法:QT调用HTTP请求相应的网站会返回 JSON 数据,解析该JSON数据中包含了天气数据
步骤1:首先打开下面网站,进行用户注册,随后会生成id和密码(后续http请求的网址中要包含的)
实时天气预报api 24小时天气预报接口 实时气象预警 空气质量预报
或者通过别的api进行访问天气情况,使用时候需更换后面的city_id的值即可
http://t.weather.itboy.net/api/weather/city/101030100
步骤2:网站主页有相应的网址访问示例,如果想访问特定城市,需在链接后面拼接城市id等数据
步骤3:复制所有json内容,通过以下网站可以解析这些数据,选择你所需要字段名

步骤四:除此之外,你还需要有存储着城市姓名和城市id的文档,以便于你后期搜索城市天气时候,可以根据该文档获取到城市的city_id,然后拼接网址进行HTTP请求
通过以下代码可以实现查询城市id时,不用每次都重新打开json文档,而是把json文档中的city_name和 city_id键值对存入QMap中,当需要时直接在QMap中进行查找并返回相应的city_id
#include <QFile>
#include <QDebug>
#include <QJsonArray>
#include <QJsonObject>
#include <QJsonDocument>
#include "citycodeutils.h"
CityCodeUtils::CityCodeUtils() {}
// 根据用户输入的城市名在QMap中检索,返回相应的code_id
QString CityCodeUtils::getCityCodeFromName(QString cityName)
{
// 如果QMap为空,则调用初始化函数,解析json数据提取城市名字和id存入QMap中
if(cityMap.isEmpty()){
initCityMap();
}
QString city_name2 = QString("%1市").arg(cityName); //假设用户输入的不带市
QString city_name3 = QString("%1县").arg(cityName); //假设用户输入的不带县
QString city_name4 = cityName; //假设用户输入的带市,但是我们不需要市
if (city_name4.contains("市")) {
city_name4.remove("市");
}
QString city_name5 = cityName; //假设用户输入的带县,但是我们不需要县
if (city_name5.contains("县")) {
city_name5.remove("县");
}
QMap<QString, QString>::const_iterator it = cityMap.constBegin(); //迭代器指向QMap的起始
while (it != cityMap.constEnd()) { //利用迭代器遍历QMap
if(it.key() == cityName || it.key() == city_name2 || it.key() == city_name3 || it.key() == city_name4 ||it.key() == city_name5){
return it.value(); //返回对应的code_id
break; //返回后结束当前循环
}
++it;
}
return 000000; //若没有找到匹配的,则返000000,代表错误代码
}
// 负责解析本地的json数据,提取出城市名字和code_id存入QMap中
void CityCodeUtils::initCityMap()
{
QFile file(":/aaa.json");
file.open(QIODevice::ReadOnly);
QString data = QString::fromUtf8(file.readAll());
file.close();
QJsonDocument jsonDoc = QJsonDocument::fromJson(data.toUtf8()); //将读取的json字符串转化为jsonDocument文档
// 准备一个 QMap 来存储解析的数据
QMap<QString, QString> dataMap;
// 如果jsonDocument文档是一个数组
if (!jsonDoc.isNull() && jsonDoc.isArray()) {
QJsonArray jsonArray = jsonDoc.array(); //将json文档转化为一个jsonArray数组
for (const QJsonValue &value : jsonArray) { //遍历数组中的每个对象
if (value.isObject()) {
QJsonObject jsonObj = value.toObject(); //将数组中的对象赋值给json对象,然后根据键值对提取json对象中的内容
QString city_name = jsonObj["city_name"].toString();
QString city_code = jsonObj["city_code"].toString();
cityMap.insert(city_name,city_code); //向QMap中插入键值对
}
}
}
}
2.4 如何实现将网站返回的json天气数据缓存下来
解决方法:先检查是否有本地缓存的json天气数据,如果有的话,则进一步判断该文件是否过期,如果没过期的话,就解析旧的json天气数据。否则进行http请求,将返回的json天气数据保存下来,然后进行解析该数据,往控件上显示。否则,旧进行http请求。
并且当用户搜索相应的城市天气时,我先不进行http请求,我检查一下这个新的网址和旧的网址是不是一样的,如果是一样的,那就重复上述步骤,查看本地是否有缓存的json天气数据,以及该数据是否过期。如果文件不存在或已过期,或者是网址与旧的网址不同,那么就进行http请求。
/*解析json数据*/
void Widget::praseJsonData(QString jsonString) {
// 将JSON字符串转换为QJsonDocument文档
QJsonDocument jsonDoc = QJsonDocument::fromJson(jsonString.toUtf8());
// 检查JSON文档是否有效
if (jsonDoc.isNull() || !jsonDoc.isObject()) {
qDebug() << "Invalid JSON data!";
return;
}
// 把JSON文档转化为json对象
QJsonObject jsonObj = jsonDoc.object();
// 城市信息解析(**城市名称,省会名称**)
if (jsonObj.contains("cityInfo") && jsonObj["cityInfo"].isObject()) {
QJsonObject cityInfo = jsonObj["cityInfo"].toObject();
QString city = cityInfo.value("city").toString("未知城市");
QString parent = cityInfo.value("parent").toString("未知省份");
QString updateTime = cityInfo.value("updateTime").toString("未知时间");
ui->label_city->setText(QString("%1, %2").arg(parent).arg(city)); // *设置城市名称和省份
}
// 天气数据解析
if (jsonObj.contains("data") && jsonObj["data"].isObject()) {
QJsonObject data = jsonObj["data"].toObject();
ui->label_WeatherNum->setText(data.value("wendu").toString("N/A") + "℃"); // *设置当天温度
ui->label_WetNum->setText(data.value("shidu").toString("N/A")); // *设置当天湿度
ui->label_AirNum->setText(data.value("quality").toString("N/A")); // *设置当天空气质量
qint16 Pm25 = data.value("pm25").toInt(-1); // 获取当天的pm2.5
ui->label_PmNum->setText(QString::number(Pm25)); // *设置当天PM2.5
ui->label_GanMao->setText(data.value("ganmao").toString("N/A")); // *设置提示信息
// 解析昨天的天气
if (data.contains("yesterday") && data["yesterday"].isObject()) {
QJsonObject yestObj = data["yesterday"].toObject();
QString high = extractTemperature(yestObj.value("high").toString()); // 获取并提取昨天的最高温度
dayHighTem[0] = high;
QString low = extractTemperature(yestObj.value("low").toString()); // 获取并提取昨天的最低温度
dayLowTem[0] = low;
QString type = yestObj.value("type").toString("未知"); // 获取昨天的天气状况
QString date = yestObj.value("ymd").toString("未知日期"); // 获取昨天的日期
qint16 aqi = yestObj.value("aqi").toInt(-1); // 获取昨天的空气质量指数
ui->label_01->setStyleSheet(aqi <= 50 ? "background-color: rgb(85, 170, 0);" :
(aqi <= 100 ? "background-color: rgb(255, 146, 21);" :
"background-color: rgb(255, 0, 0);"));
QStringList parts = date.split("-");
QString lastDate = parts.size() == 3 ? QString("%1-%2").arg(parts[1]).arg(parts[2]) : "未知日期";
ui->label_date1->setText(lastDate); // *设置昨天的日期
ui->label_sweather01->setText(type); // *设置昨天的天气
auto it = mTypeMap.find(type); // *设置昨天的天气图片
if (it != mTypeMap.end()) {
QString IconPath = it.value();
QPixmap pixmap(IconPath);
ui->label_sweather1->setPixmap(pixmap);
} else {
qDebug() << "Weather type not found in mTypeMap:" << type;
}
ui->label_01->setText(aqi <= 50 ? "优" : (aqi <= 100 ? "良" : "差")); // *设置昨天的空气质量
ui->label_windDir1->setText(yestObj.value("fx").toString("未知风向")); // *设置昨天的风向
ui->label_windDir01->setText(yestObj.value("fl").toString("未知风级")); // *设置昨天的风级
}
// 解析未来天气预报
if (data.contains("forecast") && data["forecast"].isArray()) {
QJsonArray forecastArray = data["forecast"].toArray();
int i = 1;
for (const QJsonValue &value : forecastArray) {
if (value.isObject()) {
QJsonObject forecast = value.toObject();
QString high = extractTemperature(forecast.value("high").toString()); //获取并提取出最高温度
dayHighTem[i] = high;
QString low = extractTemperature(forecast.value("low").toString()); //获取并提取出最低温度
dayLowTem[i] = low;
QString type = forecast.value("type").toString("未知"); //获取天气情况
QString date = forecast.value("ymd").toString("未知日期"); //获取日期
QString fx = forecast.value("fx").toString("未知风向"); //获取风向
QString fl = forecast.value("fl").toString("未知风级"); //获取风级
qint16 aqi = forecast.value("aqi").toInt(-1); //获取空气指数
QStringList parts = date.split("-");
QString lastDate = parts.size() == 3 ? QString("%1-%2").arg(parts[1]).arg(parts[2]) : "未知日期";
if(i == 1){
ui->label_WeatherStaute->setText(type); //设置当天的天气情况
ui->label_FxTitle->setText(fx); //设置当天的风向
ui->label_FxNum->setText(fl); //设置当天的风级
}
QLabel *label_day = findChild<QLabel *>(QString("label_day%1").arg(i + 1));
QLabel *label_date = findChild<QLabel *>(QString("label_date%1").arg(i + 1));
QLabel *label_sweather = findChild<QLabel *>(QString("label_sweather0%1").arg(i + 1));
QLabel *label_windDir = findChild<QLabel *>(QString("label_windDir%1").arg(i + 1));
QLabel *label_windDir0 = findChild<QLabel *>(QString("label_windDir0%1").arg(i + 1));
QLabel *label_airQuality = findChild<QLabel *>(QString("label_0%1").arg(i + 1));
if (label_day && label_date && label_sweather && label_windDir && label_windDir0 && label_airQuality) {
label_day->setText(i == 1 ? "今天" : forecast.value("week").toString("未知")); //*设置星期几
label_date->setText(lastDate); //*设置日期
label_sweather->setText(type); //*设置天气情况
label_windDir->setText(fx); //*设置风向
label_windDir0->setText(fl); //*设置风级
QString airStatus = (aqi <= 50) ? "优" : ((aqi <= 100) ? "良" : "差");
label_airQuality->setText(airStatus); //*设置空气质量
label_airQuality->setStyleSheet(aqi <= 50 ? "background-color: rgb(85, 170, 0);" :
(aqi <= 100 ? "background-color: rgb(255, 146, 21);" :
"background-color: rgb(255, 0, 0);"));
auto it = mTypeMap.find(type);
if (it != mTypeMap.end()) {
QString IconPath = it.value();
QPixmap pixmap(IconPath);
if(i == 1){ //*设置当天的天气质量图片
ui->label_WeatherImage->setPixmap(pixmap);
}
QLabel *label_weatherIcon = findChild<QLabel *>(QString("label_sweather%1").arg(i + 1));
if (label_weatherIcon) {
label_weatherIcon->setPixmap(pixmap); //*设置天气质量图片
}
}
} else {
qDebug() << "One or more labels not found for day" << i;
}
if(i < 5){
i++;
}
}
}
}
}
update(); // 更新界面
}
//获取http请求的数据并将返回数据保存到本地文档中
void Widget::readHttpRequest()
{
int resCode = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt(); // 获取返回码,正确获取为200,错误时为404
qDebug() << "resCode:" << resCode;
if(resCode == 200 && reply->error() == QNetworkReply::NoError){
QString response = QString::fromUtf8(reply->readAll()); //获取返回信息
QFile file("C:/Users/mi/Desktop/Qt_Project/Weather-forecast/json_data");
if(!file.open(QIODevice::WriteOnly | QIODevice::Truncate)){
qDebug() << "文件打开失败";
}
file.write(response.toLocal8Bit()); //将返回的json数据写入文件中
file.close();
praseJsonData(response); //解析json数据
}else{
qDebug() << "Error:" << reply->errorString(); //获取错误信息
QMessageBox::warning(this,"错误","网络请求失败",QMessageBox::Ok);
}
}
//检查本地json文件是否存在,以及是否该重新访问
void Widget::checkAndLoadWeatherData()
{
QString cacheFilePath = "C:/Users/mi/Desktop/Qt_Project/Weather-forecast/json_data"; // 缓存文件路径
QFileInfo cacheFileInfo(cacheFilePath);
if (cacheFileInfo.exists()) {
// 文件存在,检查是否过期
QDateTime lastModified = cacheFileInfo.lastModified();
QDateTime currentTime = QDateTime::currentDateTime();
qint64 elapsedSecs = lastModified.secsTo(currentTime);
qDebug() << "缓存存在,距离上次修改的时间:" << elapsedSecs << "秒";
if (elapsedSecs <= 3600) { // 如果文件修改时间在1小时内
// 解析本地缓存文件
QFile cacheFile(cacheFilePath);
if (cacheFile.open(QIODevice::ReadOnly)) {
QString jsonData = QString::fromLocal8Bit(cacheFile.readAll());
cacheFile.close();
qDebug() << "使用本地缓存数据";
praseJsonData(jsonData);
return; // 使用缓存数据后返回
}
}
}
// 如果缓存不存在或已过期,则发送 HTTP 请求
qDebug() << "缓存无效,发送HTTP请求获取数据";
QUrl url(website);
QNetworkRequest request(url);
reply = manager->get(request);
}
//根据用户输入的城市名进行查询天气数据
void Widget::weatherSearch()
{
QString ser_city_name = ui->lineEdit_searchData->text(); //获取用户输入的城市名
QString cityCode = citycodeUtils->getCityCodeFromName(ser_city_name); //获取返回的城市id
if(cityCode == 000000){ //返回错误代码,则不进行http请求
QMessageBox msgBox;
msgBox.setText("未检索到城市.");
msgBox.exec();
}else{
website = QString("http://t.weather.itboy.net/api/weather/city/%1").arg(cityCode); //拼接要访问的网址
if(website == lastwebsite){ //如果此次访问的和上次访问的一样,则不进行http请求
checkAndLoadWeatherData();
}else{
lastwebsite = website;
QUrl url(website);
QNetworkRequest request(url);
reply = manager->get(request); //进行http请求
}
}
}
2.5 如何在控件上绘制6天的高低温折线图?
解决方法:重写事件过滤函数,为控件widget_0404和widget_0405安装事件过滤器
检测到绘制信号时候,调用函数进行绘制高低温曲线
/*绘制低温曲线*/
void Widget::drawTempLineHigh()
{
QPainter painter(ui->widget_0404);
painter.setRenderHint(QPainter::Antialiasing, true); //启用抗锯齿
int sum = 0;
int ave;
int offset = 0;
int middle = ui->widget_0404->height() / 2;
QFont font("Arial", 10);
painter.setFont(font);
for (int i = 0; i < 6; i++) {
sum += dayHighTem[i].toInt();
}
ave = sum / 6;
QPoint points[6];
for (int i = 0; i < 6; i++) {
points[i].setX(lab[i]->x() + lab[i]->width() / 2); //当前点的横坐标位置与其头顶上方的空气质量组件有关
offset = dayHighTem[i].toInt() - ave; //偏移值等于当天温度-平均值,可乘以适当倍数以增加曲率
points[i].setY(middle - offset); //因为画笔直接与当前窗口关联了,所以纵坐标等于当前窗口高度-偏移值
painter.setPen(Qt::yellow);
painter.setBrush(Qt::yellow);
painter.drawEllipse(points[i], 2, 2); //绘制圆点
QString temperatureText = QString("%1℃").arg(dayHighTem[i]);
QPoint textPosition(points[i].x() - 7, points[i].y() + 15); //调整文字位置
painter.setPen(QColor(Qt::white));
painter.drawText(textPosition, temperatureText); //在点的下方绘制温度值
}
painter.setPen(Qt::yellow);
for (int i = 0; i < 5; i++) {
painter.drawLine(points[i], points[i + 1]); //绘制5条温度西线
}
}
/*绘制高温曲线*/
void Widget::drawTempLineLow()
{
QPainter painter(ui->widget_0405);
painter.setRenderHint(QPainter::Antialiasing, true);
int sum = 0;
int ave;
int offset = 0;
int middle = ui->widget_0405->height() / 2;
QFont font("Arial", 10);
painter.setFont(font);
for (int i = 0; i < 6; i++) {
sum += dayLowTem[i].toInt();
}
ave = sum / 6;
QPoint points[6];
for (int i = 0; i < 6; i++) {
points[i].setX(lab[i]->x() + lab[i]->width() / 2);
offset = dayLowTem[i].toInt() - ave;
points[i].setY(middle - offset);
painter.setPen(QColor(35, 255, 255));
painter.setBrush(QColor(35, 255, 255));
painter.drawEllipse(points[i], 2, 2);
QString temperatureText = QString("%1℃").arg(dayLowTem[i]);
QPoint textPosition(points[i].x() - 7, points[i].y() + 15);
painter.setPen(QColor(Qt::white));
painter.drawText(textPosition, temperatureText);
}
painter.setPen(QColor(35, 255, 255));
for (int i = 0; i < 5; i++) {
painter.drawLine(points[i], points[i + 1]);
}
}
/*事件过滤函数*/
bool Widget::eventFilter(QObject *watched, QEvent *event)
{
if(watched == ui->widget_0404 && event->type() == QEvent::Paint){
drawTempLineHigh();
return true;
}
if(watched == ui->widget_0405 && event->type() == QEvent::Paint){
drawTempLineLow();
return true;
}
return QWidget::eventFilter(watched,event);
}
三.HTTP通信知识补充
3.1 QT实现HTTP通信
HTTP(超文本传输协议)是用于分布式、协作式和超媒体信息系统的应用层协议,是万维网(WWW)的数据通信的基础。了解HTTP的基本概念对于理解现代网络通信至关重要。以下是HTTP的一些核心概念:
| 请求和响应: | HTTP是一个基于请求-响应模式的协议。客户端(通常是Web浏览器)向服务器发送一个HTTP请求,然后服务器返回一个HTTP响应。请求包含请求的资源(如网页),而响应包含请求的资源的内容。 | |
| HTTP方法: |
|
|
| 状态码: |
|
Qt中的HTTP编程涉及到使用Qt中的网络模块来进行HTTP请求和处理HTTP响应。
QNetworkAccessManager,QNetworkRequest,QNetworkReply
以下程序展示了如何使用Qt发送一个简单的HTTP请求并处理响应
//包含在头文件中
QNetworkAccessManager *manager;
QNetworkReply *reply;
//包含在构造函数中
manager = new QNetworkAccessManager(this);
QNetworkRequest request(QUrl("http://t.weather.itboy.net/api/weather/city/101010100"));
reply = manager->get(request);
connect(reply, &QNetworkReply::finished, this, &Widget::readHttpRequest);
//或者绑定完成信号与manager对象更好
//connect(manager,&QNetworkAccessManager::finished, this, &Widget::readHttpRequest);
//自定义函数
void Widget::readHttpRequest()
{
int resCode = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt(); // 获取返回码,正确获取为200,错误时为404
qDebug() << "resCode:" << resCode;
if(resCode == 200 && reply->error() == QNetworkReply::NoError){
QString response = QString::fromUtf8(reply->readAll()); //获取返回信息
qDebug() << "response:" << response;
}else{
qDebug() << "Error:" << reply->errorString(); //获取错误信息
QMessageBox::warning(this,"错误","网络请求失败",QMessageBox::Ok);
}
}
3.2 Qt生成JSON数据
JSON(JavaScript ObjectNotation)是一种轻量级的数据交换格式。它易于人阅读和编写,同时也易于机器解析和生成。JSON是基于JavaScript的一个子集,尽管它是独立于语言的,且有多种语言支持。JSON常用于网络应用程序中的数据传输,尤其是在Web应用程序中与后端服务器通信。
在Qt中生成JSON数据并将其保存到文件的一个基本示例涉及使用QJsonDocument、QJsonObject和QJsonArray类。以下是创建一个简单JSON对象并将其保存到文件的示例代码。
#include <QJsonDocument>
#include <QJsonObject>
#include <QFile>
#include <QDebug>
#include <QJsonArray>
QJsonObject rootObj; //创建一个json对象,键值对
rootObj["cityid"] = "1010100";
rootObj["date"] = "2024-11-13";
rootObj["weather"] = "雨夹雪";
QJsonArray jsonArr; //创建一个JSON数组
jsonArr.append("C++");
jsonArr.append("Python");
rootObj["languages"]=jsonArr; //将数组添加到JSON对象
QJsonDocument JsonDoc(rootObj); //将json对象转化为json文档
QByteArray json = JsonDoc.toJson(); //将json文档转化为字符串
QFile file("C:/Users/mi/Desktop/Qt_Project/Qt_JsonData/jsonData");
if(!file.open(QIODevice::WriteOnly | QIODevice::Truncate)){
qDebug() << "文件打开失败";
}
file.write(json); //写入文件中
file.close();
3.3 Qt解析JSON数据
在Qt中解析JSON数据通常涉及到使用QJsonDocument、QJsonObject和QJsonArray类。这些类提供了处理JSON数据的必要工具,使您能够从JSON字符串中提取信息、遍历JSON对象或数组,并访问具体的数据项。
以下是如何在Qt中解析这个JSON字符串的步骤:
示例1:json文档中只包含1个对象
// 1.使用了原始字符串字面量来定义JSON字符串,这样可以避免转义特殊字符
QString jsonString = R"(
{
"name": "John Doe",
"age": 30,
"email": "john.doe@example.com",
"skills": ["C++", "Python", "JavaScript"]
}
)";
// 2.将JSON字符串转换为QJsonDocument文档
QJsonDocument jsonDoc = QJsonDocument::fromJson(jsonString.toUtf8());
// 3.检查JSON文档是否包含一个对象
if (!jsonDoc.isNull() && jsonDoc.isObject()) {
// 3.1获取JSON对象并访问其键值
QJsonObject jsonObj = jsonDoc.object();
QString name = jsonObj["name"].toString();
int age = jsonObj["age"].toInt();
QString email = jsonObj["email"].toString();
qDebug() << "Name:" << name;
qDebug() << "Age:" << age;
qDebug() << "Email:" << email;
// 3.2获取JSON对象中的数组
if (jsonObj.contains("skills") && jsonObj["skills"].isArray()) {
QJsonArray skillsArray = jsonObj["skills"].toArray();
for (const QJsonValue &value : skillsArray) {
qDebug() << "Skill:" << value.toString();
}
}
} else {
qDebug() << "Invalid JSON.";
}
示例2:json文档中包含多个对象
// 1.定义一个包含多个对象的JSON字符串
QString jsonString = R"(
[
{
"name": "小李",
"age": 18,
"email": "xiaoli.doe@example.com",
"skills": ["C++", "Python", "JavaScript"]
},
{
"name": "小美",
"age": 25,
"email": "xiaomei.smith@example.com",
"skills": ["Java", "C#", "PHP"]
}
]
)";
// 2.将JSON字符串转换为QJsonDocument对象
QJsonDocument jsonDoc = QJsonDocument::fromJson(jsonString.toUtf8());
// 3.检查JSON文档是否包含一个数组,多个对象保存到一个数组中
if (!jsonDoc.isNull() && jsonDoc.isArray()) {
QJsonArray jsonArray = jsonDoc.array(); //3.1获取json文档中的数组
for (const QJsonValue &value : jsonArray) { //3.2遍历数组中的每个对象
if (value.isObject()) {
QJsonObject jsonObj = value.toObject(); //3.3将数组中的对象赋值给json对象,然后根据键值对提取json对象中的内容
QString name = jsonObj["name"].toString();
int age = jsonObj["age"].toInt();
QString email = jsonObj["email"].toString();
qDebug() << "Name:" << name;
qDebug() << "Age:" << age;
qDebug() << "Email:" << email;
if (jsonObj.contains("skills") && jsonObj["skills"].isArray()) {
QJsonArray skillsArray = jsonObj["skills"].toArray();
for (const QJsonValue &skillValue : skillsArray) {
qDebug() << "Skill:" << skillValue.toString();
}
}
}
}
} else {
qDebug() << "Invalid JSON or not an array.";
}
3.4 Qt解析JSON数据并存储到QMap类中
// JSON 字符串
QString jsonString = R"(
{
"name": "John Doe",
"age": "30",
"email": "john.doe@example.com"
}
)";
// 将 JSON 字符串转换为 QJsonDocument
QJsonDocument jsonDoc = QJsonDocument::fromJson(jsonString.toUtf8());
// 准备一个 QMap 来存储解析的数据
QMap<QString, QString> dataMap;
// 解析 JSON 对象并填充 QMap
if (!jsonDoc.isNull() && jsonDoc.isObject()) {
QJsonObject jsonObj = jsonDoc.object();
for (auto key : jsonObj.keys()) {
dataMap[key] = jsonObj.value(key).toString();
}
} else {
qDebug() << "Invalid JSON...";
}
// 打印 QMap 内容
for (auto key : dataMap.keys()) {
qDebug() << key << ": " << dataMap[key];
}
四.整体代码实现如下
tunnek/mimi: QT——天气预报项目 (github.com)
更多推荐

所有评论(0)