[QT]天气显示小控件

功能

获取当前网络下对应区县的实时温度、天气、地址、空气质量、24小时天气预测,QT环境5.15.2,地理限制,均使用国内API,国外是否支持需要查询对应文档。

开源代码链接

基于Qt的天气显示小控件
后续会不定时更新UI库资源

运行时UI展示

​​夜间晴朗天气
在这里插入图片描述

Click_weather

功能实现

数据获取

  • 通过访问“http://myip.ipip.net”网站获取公网IP。
  • 经纬度API为百度地图普通IP定位API,通过公网IP获取所在区县经纬度
  • 天气API为和风天气API,获取实时天气、实时空气资料、24h天气预测

数据显示

基本都是Label显示,24h控件由水平布局HBoxLayout,数据向内部item写入,并添加触摸和鼠标支持。

素材

素材主要为各种天气图标,来源于阿里巴巴矢量图标库和豆包生成,有些经过细微的修改。仓库中包含每个图标对应的ps文件,png文件,如果是夜间图标,也包含对应的ai文件。

UI风格参考

参考VIVO ,Origin系统桌面天气原子组件,其24h温度是曲线实现,暂时没有头绪,简化一下直接由数字实现
在这里插入图片描述

资源文件索引

每种天气对应哪个素材由和风天气API获取,回传数据中有一个“icon”参数,就是对应的和风天气素材库对应图标的号码,我们在资源文件中的名称也参考这个号码。

应用实现

数据获取步骤

获取公网IP

http://myip.ipip.net 发送请求,回传数据中包含当前设备的公网IP
此数据只有百度API获取当前IP所在区的经纬度有用
在这里插入图片描述

获取经纬度

向百度地图,普通IP定位 API发送请求,传入参数为,之前获取的IP地址、API 的AK码、经纬度坐标系格式为gcj02,而不是百度默认的经纬度坐标系。
此步骤主要获取xy,分别为经度和维度,为后续获取天气信息
在这里插入图片描述

获取实时天气

和风天气-实时天气API,发送请求,传入参数为API_Host,经纬度,API_Key。
获取的信息中主要使用tempicontext
在这里插入图片描述

获取实时空气质量

和风天气-实时空气质量API发送请求,传入参数和之前一样
主要使用category参数
在这里插入图片描述

获取24h天气预测

和风天气-按小时预测API发送请求,传入参数和之前一样
主要使用fxTime,tempicon, 分别作为24h预测中时间、图标索引、温度
在这里插入图片描述

代码框架

Click

主函数Clic类,主要实现各种控件的初始化内容,以及各API回传数据槽函数。
Click.cpp

#include "click.h"
#include <QLabel>
#include <QSslSocket>
#include <QFile>
#include <QPainter>
#include <QPalette>
#include <QJsonArray>

/* ------------------------Click---------------------------- */

Click::Click(QWidget *parent)
    : QMainWindow(parent)
{
   
   
    vWidthRatio = 1.0;
    hHeightRatio = 1.0;
    this->setGeometry(0, 0, 900 * hHeightRatio, 300 * vWidthRatio);
    this->setStyleSheet("background-color: rgb(193, 193, 193);");


    weatherAPI = new WeatherAPI();      // 初始化天气API类
    checker = new IPChecker();          // 初始化经纬度获取类

    initWeathrUI();

    // 初始化定时器
    autoRefreshTimer = new QTimer(this);
    connect(autoRefreshTimer, &QTimer::timeout, this, &Click::refreshData);

    // 设置1小时刷新一次(3600000毫秒)
    autoRefreshTimer->start(3600000);

    connect(weatherAPI, &WeatherAPI::weatherDataReceived, this, &Click::updateRealTimeWeather);
    connect(checker, &IPChecker::errorOccurred, this, &Click::IPCheckerror);
    connect(checker, &IPChecker::locationReceived, this, &Click::locationChecked);
    connect(checker, &IPChecker::coordinateReceived, this, &Click::coordinateChecked);
    connect(weatherAPI, &WeatherAPI::airQualityDataReceived, this, &Click::airQualityChecked);
    connect(weatherAPI, &WeatherAPI::hourlyWeatherDataReceived, this, &Click::hourlyWeatherChecked);
}

Click::~Click() {
   
   }

//
/**
 * @brief 初始化天气UI
 */
void Click::initWeathrUI(){
   
   
    QPalette whiteColor;
    whiteColor.setColor(QPalette::WindowText, Qt::white);

    // 天气显示区域
    weatherDisplayWidget = new QWidget(this);
    weatherDisplayWidget->setGeometry(10 * hHeightRatio, 10 * vWidthRatio, 886 * hHeightRatio, 270 * vWidthRatio);
    weatherDisplayWidget->setStyleSheet("background-color: rgb(255, 255, 255); border-radius: 20px;");

    //左侧当前天气ICON
    weatherIcon = new QLabel(weatherDisplayWidget);
    weatherIcon->setGeometry(40 * hHeightRatio, 35 * vWidthRatio, 200 * hHeightRatio, 200 * vWidthRatio);
    weatherIcon->setAlignment(Qt::AlignCenter);

    //右侧天气信息
    QWidget *weatherInfoWidget = new QWidget(weatherDisplayWidget);
    weatherInfoWidget->setGeometry(280 * hHeightRatio, 35 * vWidthRatio, 566 * hHeightRatio, 200 * vWidthRatio);

    //天气背景图
    weatherBackgroundPic = new QLabel(weatherInfoWidget);
    weatherBackgroundPic->setGeometry(0 * hHeightRatio, 0 * vWidthRatio, 566 * hHeightRatio, 200 * vWidthRatio);
    weatherBackgroundPic->setScaledContents(true);
    weatherBackgroundPic->setStyleSheet("border-radius: 10px;");

    //温度
    tempLabel = new QLabel(weatherInfoWidget);
    tempLabel->setGeometry(15 * hHeightRatio, 8 * vWidthRatio, 70 * hHeightRatio, 55 * vWidthRatio);
    tempLabel->setFont(QFont("黑体", 38));
    tempLabel->setText("");
    tempLabel->setStyleSheet("background: transparent;font-weight: bold;");
    tempLabel->setPalette(whiteColor);

    //摄氏度
    QLabel *tempSignLabel = new QLabel(weatherInfoWidget);
    tempSignLabel->setGeometry(82 * hHeightRatio, 11 * vWidthRatio, 20 * hHeightRatio, 20 * vWidthRatio);
    tempSignLabel->setFont(QFont("黑体", 10));
    tempSignLabel->setText("℃");
    tempSignLabel->setStyleSheet("background: transparent;");
    tempSignLabel->setPalette(whiteColor);

    //天气状况
    conditionLabel = new QLabel(weatherInfoWidget);
    conditionLabel->setGeometry(82 * hHeightRatio, 34 * vWidthRatio, 100 * hHeightRatio, 24 * vWidthRatio);
    conditionLabel->setFont(QFont("黑体", 15));
    conditionLabel->setText("");
    conditionLabel->setStyleSheet("background: transparent;");
    conditionLabel->setPalette(whiteColor);

    //空气质量
    airQualityLabel = new QLabel(weatherInfoWidget);
    airQualityLabel->setGeometry(430 * hHeightRatio, 13 * vWidthRatio, 120 * hHeightRatio, 24 * vWidthRatio);
    airQualityLabel->setFont(QFont("黑体", 15));
    airQualityLabel->setText("");
    airQualityLabel->setStyleSheet("background: transparent;");
    airQualityLabel->setPalette(whiteColor);
    airQualityLabel->setAlignment(Qt::AlignRight | Qt::AlignVCenter);

    //地址
    addressLabel = new QLabel(weatherInfoWidget);
    addressLabel->setGeometry(490 * hHeightRatio, 40 * vWidthRatio, 60 * hHeightRatio, 20 * vWidthRatio);
    addressLabel->setFont(QFont("黑体", 11));
    addressLabel->setText("");
    addressLabel->setStyleSheet("background: transparent;");
    addressLabel->setPalette(whiteColor);

    //地址图标
    QString locationIconPath = ":/icons/location.png";
    if(QFile::exists(locationIconPath)){
   
   
        QPixmap locationIcon(locationIconPath);
        locationIcon = locationIcon.scaled(15 * hHeightRatio, 15 * vWidthRatio, Qt::KeepAspectRatio, Qt::SmoothTransformation);
        QLabel *locationIconLabel = new QLabel(weatherInfoWidget);
        locationIconLabel->setGeometry(470 * hHeightRatio, 43 * vWidthRatio, 15 * hHeightRatio, 15 * vWidthRatio);
        locationIconLabel->setPixmap(locationIcon);
        locationIconLabel->setAlignment(Qt::AlignVCenter);
        locationIconLabel->setStyleSheet("background: transparent;");
    }

    //24小时天气预测
    QWidget *dailyWeatherForecastWidget = new QWidget(weatherInfoWidget);
    dailyWeatherForecastWidget->setGeometry(18 * hHeightRatio, 68 * vWidthRatio, 530 * hHeightRatio, 120 * vWidthRatio);
    dailyWeatherForecastWidget->setStyleSheet("background-color: rgba(255, 255, 255, 0.1); border-radius: 20px;");

    // 创建滚动区域用于显示小时天气预报
    hourlyScrollArea = new HourlyWeatherScrollArea(dailyWeatherForecastWidget);
    hourlyScrollArea->setGeometry(0 * hHeightRatio, 0 * vWidthRatio,
                                530 * hHeightRatio, 120 * vWidthRatio);
    hourlyScrollArea->setRatios(vWidthRatio, hHeightRatio);

    //创建加载图标
    loadingIcon = new LoadingIcon(weatherDisplayWidget);
    loadingIcon->setGeometry(10 * hHeightRatio, 10 * vWidthRatio, 40 * hHeightRatio, 40 * vWidthRatio);
    // 连接按钮点击信号
    connect(loadingIcon->getButton(), &QPushButton::clicked, this, [this](){
   
   
        loadingIcon->startRotation();       // 点击时开始旋转
        refreshData();         
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值