PYQT6 和风天气预报

在此之前我想问下,各位大神,微信小程序里的腾讯天气背景谁可以提取,好想要啊,以前保存的删掉了,现在只有三张

做了一款天气预报小程序,主要麻烦是素材,找素材累死我了

先将准备工作:

1,环境这我就不说了

2,和风天气API:申请key和风天气 | 商业气象服务商, 天气预报,灾害预警,台风路径,卫星云图,天气API/SDK/APP, 天气插件, 历史天气, 气象可视化

3,素材,建议直接使用和风的图标字体,方便

4,时间主要考虑数据处理方式,虽然条条大路通罗马,怎么滴都能实现你需要的效果

代码模块:

1,API模块,通过API调用实时天气、24小时天气、空气质量、未来7天天气和生活指数,还有日出日落时间

import requests
from datetime import datetime
from pprint import pprint
from WeatherAPI.GOAPI import CityCodeLookup


class WeatherAPI:
    def __init__(self, api_key):
        self.api_key = api_key
        self.city_code_lookup = CityCodeLookup(api_key)

    def get_weather_data_by_city_name(self, city_name, data_types=['all']):
        city_id = self.city_code_lookup.lookup_city_code(city_name)
        if city_id:
            result = {}

            if 'realtime' in data_types or 'all' in data_types:
                result['realtime'] = self.get_realtime_weather_data(city_id)

            if 'future' in data_types or 'all' in data_types:
                result['future'] = self.get_future_weather_data(city_id)

            if '24hour' in data_types or 'all' in data_types:
                result['24hour'] = self.get_24hour_weather_data(city_id)

            if 'air_quality' in data_types or 'all' in data_types:
                result['air_quality'] = self.get_air_quality_data(city_id)

            if 'sunrise_sunset' in data_types or 'all' in data_types:
                result['sunrise_sunset'] = self.get_sunrise_sunset_data(city_id)

            if 'life_indices' in data_types or 'all' in data_types:
                result['life_indices'] = self.get_life_indices_data(city_id)

            return result
        else:
            return {"error": "Failed to find the city code"}


    def get_realtime_weather_data(self, city_id):
        # 和风天气 API 的 URL 格式 - 实时天气
        url = f"https://devapi.qweather.com/v7/weather/now?location={city_id}&key={self.api_key}"
        try:
            response = requests.get(url)
            if response.status_code == 200:
                data = response.json()
                # 提取需要的字段
                realtime_data = {
                    "最近更新时间": self._extract_time(data["updateTime"]),
                    "温度": data["now"]["temp"] + "°",
                    "体感温度": data["now"]["feelsLike"] + "°",
                    "图标代码": data["now"]["icon"],
                    "天气状况": data["now"]["text"],
                    "风向": data["now"]["windDir"],
                    "风力等级": data["now"]["windScale"],
                    "相对湿度": data["now"]["humidity"] + "%",
                    "能见度": data["now"]["vis"] + "KM"
                }
                return realtime_data
            else:
                return {"error": "Failed to fetch real-time weather data"}
        except Exception as e:
            return {"error": f"Failed to fetch real-time weather data: {str(e)}"}

    def _extract_time(self, time_str):
        dt = datetime.strptime(time_str, "%Y-%m-%dT%H:%M%z")
        return dt.strftime("%H:%M")
    def _extract_month(self, time_str):
        dt = datetime.strptime(time_str, "%Y-%m-%d")
        return dt.strftime("%m-%d")

    def get_future_weather_data(self, city_id):
        """提取未来7天天气预报的关键字段"""
        url = f"https://devapi.qweather.com/v7/weather/7d?location={city_id}&key={self.api_key}"
        try:
            response = requests.get(url)
            if response.status_code == 200:
                data = response.json()
                if "code" in data and data["code"] == "200":
                    daily_data = data.get("daily", [])
                    extracted_data = [
                        {
                            "日期": self._extract_month(day["fxDate"]),
                            "白天天气图标": day["iconDay"],
                            "白天天气": day["textDay"],
                            "最高温度": day["tempMax"] + "°C",
                            "最低温度": day["tempMin"] + "°C",
                            "夜间天气图标": day["iconNight"],
                            "夜间天气": day["textNight"]
                        }
                        for day in daily_data
                    ]
                    return extracted_data
                else:
                    return {"error": "Invalid response from API"}
            else:
                return {"error": "Failed to fetch future weather data"}
        except Exception as e:
            return {"error": f"Failed to fetch future weather data: {str(e)}"}


    def get_24hour_weather_data(self, city_id):
        # 和风天气 API 的 URL 格式 - 24 小时天气预报
        url = f"https://devapi.qweather.com/v7/weather/24h?location={city_id}&key={self.api_key}"
        try:
            response = requests.get(url)
            if response.status_code == 200:
                data = response.json()
                # 提取所需字段
                extracted_data = [
                    {
                        "预报时间": self._extract_time(hour["fxTime"]),
                        "温度": hour["temp"] + "°C",
                        "天气状况": hour["text"],
                        "图标": hour["icon"],
                    }
                    for hour in data["hourly"]
                ]
                return extracted_data
            else:
                return {"error": "Failed to fetch 24-hour weather data"}
        except Exception as e:
            return {"error": f"Failed to fetch 24-hour weather data: {str(e)}"}

    def get_air_quality_data(self, city_id):
        url = f"https://devapi.qweather.com/v7/air/now?location={city_id}&key={self.api_key}"
        try:
            response = requests.get(url)
            if response.status_code == 200:
                data = response.json()
                # 提取所需字段
                current_data = {
                    "空气质量指数": data["now"]["aqi"],
                    "PM2.5": data["now"]["pm2p5"] + " μg/m³",
                    "PM10": data["now"]["pm10"] + " μg/m³",
                    "二氧化硫": data["now"]["so2"] + " μg/m³",
                    "二氧化氮": data["now"]["no2"] + " μg/m³",
                    "臭氧": data["now"]["o3"] + " μg/m³",
                    "一氧化碳": data["now"]["co"] + " mg/m³"
                }
                return {"current": current_data}
            else:
                return {"error": "Failed to fetch air quality data"}
        except Exception as e:
            return {"error": f"Failed to fetch air quality data: {str(e)}"}

    def get_sunrise_sunset_data(self, city_id):
        # 和风天气 API 的 URL 格式 - 日出日落时间
        today = datetime.now().strftime("%Y%m%d")
        url = f"https://devapi.qweather.com/v7/astronomy/sun?location={city_id}&date={today}&key={self.api_key}"

        try:
            response = requests.get(url)
            if response.status_code == 200:
                data = response.json()
                # 提取所需的日出日落数据
                sunrise_sunset_data = {
                    "日出": self._extract_time(data["sunrise"]),
                    "日落": self._extract_time(data["sunset"])
                }

                return {"sunrise_sunset": sunrise_sunset_data}
            else:
                return {"error": "Failed to fetch sunrise sunset data"}
        except Exception as e:
            return {"error": f"Failed to fetch sunrise sunset data: {str(e)}"}


    def get_life_indices_data(self, city_id, date=None):
        today = datetime.now().strftime("%Y%m%d")
        indices = [str(i) for i in range(1, 9)]
        url = f"https://devapi.qweather.com/v7/indices/1d?type={','.join(indices)}&location={city_id}&date={today}&key={self.api_key}"
        try:
            response = requests.get(url)
            if response.status_code == 200:
                data = response.json()
                # 提取所需的生活指数
                indices_data = {}
                for index in data["daily"]:
                    name = index["name"]
                    level = index["level"]
                    category = index["category"]
                    text = index["text"]
                    indices_data[name] = {
                        "level": level,
                        "text": text,
                        "category": category
                    }

                return {"indices": indices_data}
            else:
                return {"error": "Failed to fetch life indices data"}
        except Exception as e:
            return {"error": f"Failed to fetch life indices data: {str(e)}"}


# 示例:创建 WeatherAPI 实例
def create_weather_api_instance(api_key):
    return WeatherAPI(api_key)


if __name__ == "__main__":
    city_name = input("请输入城市名称: ")
    weather_api = WeatherAPI("你的api-key")

    # 只获取实时天气数据和未来天气预报数据
    weather_data = weather_api.get_weather_data_by_city_name(city_name, ['realtime', 'future',"sunrise_sunset"])

    if "realtime" in weather_data:
        print("实时天气数据:")
        pprint(weather_data["realtime"])

    if "future" in weather_data:
        print("未来天气预报:")
        pprint(weather_data["future"])

    if "sunrise_sunset" in weather_data:
        print("日出日落时间:")
        pprint(weather_data["sunrise_sunset"])

然后第二部做UI界面,这个很花时间,调整了好多次,鉴于自己能力有限,就只能将就了

# Form implementation generated from reading ui file 'WeatherMainUI.ui'
#
# Created by: PyQt6 UI code generator 6.7.1
#
# WARNING: Any manual changes made to this file will be lost when pyuic6 is
# run again.  Do not edit this file unless you know what you are doing.


from PyQt6 import QtCore, QtGui, QtWidgets


class Ui_weatherUIForm(object):
    def setupUi(self, weatherUIForm):
        weatherUIForm.setObjectName("weatherUIForm")
        weatherUIForm.resize(494, 907)
        weatherUIForm.setStyleSheet("background-color: rgba(255, 255, 255, 0);")
        self.horizontalLayout_5 = QtWidgets.QHBoxLayout(weatherUIForm)
        self.horizontalLayout_5.setContentsMargins(6, 6, 6, 6)
        self.horizontalLayout_5.setSpacing(0)
        self.horizontalLayout_5.setObjectName("horizontalLayout_5")
        self.frame_4 = QtWidgets.QFrame(parent=weatherUIForm)
        self.frame_4.setStyleSheet("QFrame#frame_4 {    \n"
                                   "    color: rgb(255, 255, 255);\n"
                                   "    border-radius: 10px; /* 设置圆角半径为 10 像素,可以根据需要调整 */\n"
                                   "    background-color: rgb(52, 81, 115);\n"
                                   "}")
        self.frame_4.setFrameShape(QtWidgets.QFrame.Shape.StyledPanel)
        self.frame_4.setFrameShadow(QtWidgets.QFrame.Shadow.Raised)
        self.frame_4.setObjectName("frame_4")
        self.verticalLayout_4 = QtWidgets.QVBoxLayout(self.frame_4)
        self.verticalLayout_4.setContentsMargins(0, 0, 0, 0)
        self.verticalLayout_4.setSpacing(3)
        self.verticalLayout_4.setObjectName("verticalLayout_4")
        self.horizontalLayout_8 = QtWidgets.QHBoxLayout()
        self.horizontalLayout_8.setSpacing(0)
        self.horizontalLayout_8.setObjectName("horizontalLayout_8")
        spacerItem = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Policy.Expanding,
                                           QtWidgets.QSizePolicy.Policy.Minimum)
        self.horizontalLayout_8.addItem(spacerItem)
        self.RealtimeWeather = QtWidgets.QFrame(parent=self.frame_4)
        self.RealtimeWeather.setMinimumSize(QtCore.QSize(480, 390))
        self.RealtimeWeather.setMaximumSize(QtCore.QSize(480, 390))
        self.RealtimeWeather.setStyleSheet("QFrame#RealtimeWeather {    \n"
                                           "    color: rgb(255, 255, 255);\n"
                                           "    border-radius: 10px; /* 设置圆角半径为 10 像素,可以根据需要调整 */\n"
                                           "\n"
                                           "}\n"
                                           "\n"
                                           "")
        self.RealtimeWeather.setFrameShape(QtWidgets.QFrame.Shape.StyledPanel)
        self.RealtimeWeather.setFrameShadow(QtWidgets.QFrame.Shadow.Raised)
        self.RealtimeWeather.setObjectName("RealtimeWeather")
        self.icon = QtWidgets.QLabel(parent=self.RealtimeWeather)
        self.icon.setGeometry(QtCore.QRect(260, 50, 150, 150))
        self.icon.setMinimumSize(QtCore.QSize(150, 150))
        self.icon.setMaximumSize(QtCore.QSize(150, 150))
        self.icon.setStyleSheet("color: rgb(255, 255, 255);")
        self.icon.setText("")
        self.icon.setObjectName("icon")
        self.image1 = QtWidgets.QLabel(parent=self.RealtimeWeather)
        self.image1.setGeometry(QtCore.QRect(0, 230, 481, 181))
        self.image1.setStyleSheet("image: url(res/weatherImage/下载.png);")
        self.image1.setText("")
        self.image1.setObjectName("image1")
        self.image2 = QtWidgets.QLabel(parent=self.RealtimeWeather)
        self.image2.setGeometry(QtCore.QRect(0, 230, 481, 181))
        self.image2.setStyleSheet("image: url(res/weatherImage/yin2.png);")
        self.image2.setText("")
        self.image2.setObjectName("image2")
        self.CurrentWeather = QtWidgets.QFrame(parent=self.RealtimeWeather)
        self.CurrentWeather.setGeometry(QtCore.QRect(40, 160, 261, 127))
        self.CurrentWeather.setStyleSheet("QFrame {\n"
                                          "    color: rgb(255, 255, 255);\n"
                                          "    font: \"MiSans Demibold\";\n"
                                          "    background-color: rgba(255, 255, 255, 0);\n"
                                          "    border: none;\n"
                                          "}")
        self.CurrentWeather.setFrameShape(QtWidgets.QFrame.Shape.StyledPanel)
        self.CurrentWeather.setFrameShadow(QtWidgets.QFrame.Shadow.Raised)
        self.CurrentWeather.setObjectName("CurrentWeather")
        self.horizontalLayout = QtWidgets.QHBoxLayout(self.CurrentWeather)
        self.horizontalLayout.setContentsMargins(5, 5, 5, 5)
        self.horizontalLayout.setSpacing(5)
        self.horizontalLayout.setObjectName("horizontalLayout")
        self.temp = QtWidgets.QLabel(parent=self.CurrentWeather)
        self.temp.setMinimumSize(QtCore.QSize(125, 0))
        self.temp.setMaximumSize(QtCore.QSize(125, 16777215))
        font = QtGui.QFont()
        font.setFamily("MiSans")
        font.setPointSize(60)
        font.setBold(False)
        font.setItalic(False)
        font.setWeight(50)
        font.setKerning(True)
        self.temp.setFont(font)
        self.temp.setStyleSheet("font: 60pt ")
        self.temp.setAlignment(QtCore.Qt.AlignmentFlag.AlignCenter)
        self.temp.setObjectName("temp")
        self.horizontalLayout.addWidget(self.temp)
        spacerItem1 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Policy.Expanding,
                                            QtWidgets.QSizePolicy.Policy.Minimum)
        self.horizontalLayout.addItem(spacerItem1)
        self.verticalLayout = QtWidgets.QVBoxLayout()
        self.verticalLayout.setSpacing(0)
        self.verticalLayout.setObjectName("verticalLayout")
        spacerItem2 = QtWidgets.QSpacerItem(20, 40, QtWidgets.QSizePolicy.Policy.Minimum,
                                            QtWidgets.QSizePolicy.Policy.Expanding)
        self.verticalLayout.addItem(spacerItem2)
        self.horizontalLayout_3 = QtWidgets.QHBoxLayout()
        self.horizontalLayout_3.setSpacing(0)
        self.horizontalLayout_3.setObjectName("horizontalLayout_3")
        self.aqi = QtWidgets.QLabel(parent=self.CurrentWeather)
        self.aqi.setMinimumSize(QtCore.QSize(60, 30))
        self.aqi.setMaximumSize(QtCore.QSize(60, 30))
        self.aqi.setStyleSheet("QLabel{\n"
                               "background-color: rgb(0, 170, 0);\n"
                               "border-top-left-radius:15px;\n"
                               "border-bottom-left-radius:15px;\n"
                               "}")
        self.aqi.setAlignment(QtCore.Qt.AlignmentFlag.AlignCenter)
        self.aqi.setObjectName("aqi")
        self.horizontalLayout_3.addWidget(self.aqi)
        self.feelsLike = QtWidgets.QLabel(parent=self.CurrentWeather)
        self.feelsLike.setMinimumSize(QtCore.QSize(60, 30))
        self.feelsLike.setMaximumSize(QtCore.QSize(60, 30))
        self.feelsLike.setStyleSheet("background-color: rgb(0, 170, 255);\n"
                                     "border-top-right-radius:15px;\n"
                                     "border-bottom-right-radius:15px;")
        self.feelsLike.setAlignment(QtCore.Qt.AlignmentFlag.AlignCenter)
        self.feelsLike.setObjectName("feelsLike")
        self.horizontalLayout_3.addWidget(self.feelsLike)
        self.verticalLayout.addLayout(self.horizontalLayout_3)
        self.text = QtWidgets.QLabel(parent=self.CurrentWeather)
        self.text.setMinimumSize(QtCore.QSize(110, 20))
        self.text.setMaximumSize(QtCore.QSize(110, 20))
        self.text.setLayoutDirection(QtCore.Qt.LayoutDirection.LeftToRight)
        self.text.setAlignment(QtCore.Qt.AlignmentFlag.AlignCenter)
        self.text.setWordWrap(False)
        self.text.setObjectName("text")
        self.verticalLayout.addWidget(self.text)
        self.windDir = QtWidgets.QLabel(parent=self.CurrentWeather)
        self.windDir.setMinimumSize(QtCore.QSize(110, 20))
        self.windDir.setMaximumSize(QtCore.QSize(110, 20))
        self.windDir.setAlignment(QtCore.Qt.AlignmentFlag.AlignCenter)
        self.windDir.setObjectName("windDir")
        self.verticalLayout.addWidget(self.windDir)
        spacerItem3 = QtWidgets.QSpacerItem(20, 40, QtWidgets.QSizePolicy.Policy.Minimum,
                                            QtWidgets.QSizePolicy.Policy.Expanding)
        self.verticalLayout.addItem(spacerItem3)
        self.horizontalLayout.addLayout(self.verticalLayout)
        self.image3 = QtWidgets.QLabel(parent=self.RealtimeWeather)
        self.image3.setGeometry(QtCore.QRect(0, 230, 481, 181))
        self.image3.setStyleSheet("image: url(res/weatherImage/yin1.png);")
        self.image3.setText("")
        self.image3.setObjectName("image3")
        self.label_4 = QtWidgets.QLabel(parent=self.RealtimeWeather)
        self.label_4.setGeometry(QtCore.QRect(90, 130, 71, 31))
        font = QtGui.QFont()
        font.setFamily("MiSans Medium")
        font.setPointSize(16)
        self.label_4.setFont(font)
        self.label_4.setStyleSheet("color: rgb(255, 255, 255);")
        self.label_4.setAlignment(
            QtCore.Qt.AlignmentFlag.AlignLeading | QtCore.Qt.AlignmentFlag.AlignLeft | QtCore.Qt.AlignmentFlag.AlignVCenter)
        self.label_4.setObjectName("label_4")
        self.label_5 = QtWidgets.QLabel(parent=self.RealtimeWeather)
        self.label_5.setGeometry(QtCore.QRect(60, 130, 30, 30))
        self.label_5.setStyleSheet("image: url(res/wicon/Dwei.png);")
        self.label_5.setText("")
        self.label_5.setObjectName("label_5")
        self.layoutWidget = QtWidgets.QWidget(parent=self.RealtimeWeather)
        self.layoutWidget.setGeometry(QtCore.QRect(30, 10, 441, 34))
        self.layoutWidget.setObjectName("layoutWidget")
        self.horizontalLayout_14 = QtWidgets.QHBoxLayout(self.layoutWidget)
        self.horizontalLayout_14.setContentsMargins(0, 0, 0, 0)
        self.horizontalLayout_14.setSpacing(0)
        self.horizontalLayout_14.setObjectName("horizontalLayout_14")
        self.lineEdit = QtWidgets.QLineEdit(parent=self.layoutWidget)
        self.lineEdit.setMinimumSize(QtCore.QSize(0, 30))
        self.lineEdit.setStyleSheet("    background-color: rgba(120, 120, 120, 150);\n"
                                    "   color: white;\n"
                                    "    border: none;\n"
                                    "    padding: 5px 1px;\n"
                                    "    border-top-left-radius:15px;\n"
                                    "    border-bottom-left-radius:15px;")
        self.lineEdit.setObjectName("lineEdit")
        self.horizontalLayout_14.addWidget(self.lineEdit)
        self.pushButton = QtWidgets.QPushButton(parent=self.layoutWidget)
        self.pushButton.setMinimumSize(QtCore.QSize(45, 30))
        self.pushButton.setStyleSheet("QPushButton {\n"
                                      "    background-color: rgba(120, 120, 120, 150);\n"
                                      "    color: white;\n"
                                      "    border: none;\n"
                                      "    padding: 5px 1px;\n"
                                      "    /*border-radius: 5px;*/\n"
                                      "    image: url(res/loginicon/icon_Bai/chaxun-sousuo.png);\n"
                                      "border-top-right-radius:15px;\n"
                                      "border-bottom-right-radius:15px;\n"
                                      "}\n"
                                      "\n"
                                      "QPushButton:hover {\n"
                                      "    background-color: rgb(0, 170, 255);\n"
                                      "}\n"
                                      "\n"
                                      "QPushButton:pressed {\n"
                                      "    background-color: qlineargradient(spread:pad, x1:0, y1:0, x2:1, y2:1, stop:0 rgba(10, 113, 182, 255), stop:1 rgba(50, 208, 235, 255));\n"
                                      "}")
        self.pushButton.setText("")
        self.pushButton.setObjectName("pushButton")
        self.horizontalLayout_14.addWidget(self.pushButton)
        self.horizontalLayout_13 = QtWidgets.QHBoxLayout()
        self.horizontalLayout_13.setSpacing(0)
        self.horizontalLayout_13.setObjectName("horizontalLayout_13")
        spacerItem4 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Policy.Expanding,
                                            QtWidgets.QSizePolicy.Policy.Minimum)
        self.horizontalLayout_13.addItem(spacerItem4)
        self.setbut = QtWidgets.QPushButton(parent=self.layoutWidget)
        self.setbut.setMinimumSize(QtCore.QSize(40, 30))
        self.setbut.setStyleSheet("\n"
                                  "\n"
                                  "QPushButton {\n"
                                  "    background-color: rgba(220, 220, 220, 50);\n"
                                  "\n"
                                  "    color: white;\n"
                                  "    border: none;\n"
                                  "    padding: 5px 1px;\n"
                                  "    /*border-radius: 5px;*/\n"
                                  "    image: url(res/loginicon/icon_bai64/settings.png);\n"
                                  "    border-top-left-radius:15px;\n"
                                  "    border-bottom-left-radius:15px;\n"
                                  "}\n"
                                  "\n"
                                  "QPushButton:hover {\n"
                                  "    background-color: rgba(200, 200, 200, 100);\n"
                                  "}\n"
                                  "\n"
                                  "QPushButton:pressed {\n"
                                  "    background-color: rgba(200, 200, 200, 200);\n"
                                  "}")
        self.setbut.setText("")
        self.setbut.setObjectName("setbut")
        self.horizontalLayout_13.addWidget(self.setbut)
        self.clockbut = QtWidgets.QPushButton(parent=self.layoutWidget)
        self.clockbut.setMinimumSize(QtCore.QSize(40, 30))
        self.clockbut.setStyleSheet("QPushButton {\n"
                                    "    background-color: rgba(200, 220, 220, 50);\n"
                                    "    color: white;\n"
                                    "    border: none;\n"
                                    "    padding: 5px 1px;\n"
                                    "    /*border-radius: 5px;*/\n"
                                    "    image: url(res/loginicon/icon_bai64/close_light.png);\n"
                                    "border-top-right-radius:15px;\n"
                                    "border-bottom-right-radius:15px;\n"
                                    "}\n"
                                    "\n"
                                    "QPushButton:hover {\n"
                                    "    background-color: rgb(200, 0, 0);\n"
                                    "}\n"
                                    "\n"
                                    "QPushButton:pressed {\n"
                                    "    background-color: rgb(163, 0, 0);\n"
                                    "}")
        self.clockbut.setText("")
        self.clockbut.setObjectName("clockbut")
        self.horizontalLayout_13.addWidget(self.clockbut)
        self.horizontalLayout_14.addLayout(self.horizontalLayout_13)
        self.layoutWidget.raise_()
        self.image1.raise_()
        self.icon.raise_()
        self.image2.raise_()
        self.CurrentWeather.raise_()
        self.image3.raise_()
        self.label_4.raise_()
        self.label_5.raise_()
        self.horizontalLayout_8.addWidget(self.RealtimeWeather)
        spacerItem5 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Policy.Expanding,
                                            QtWidgets.QSizePolicy.Policy.Minimum)
        self.horizontalLayout_8.addItem(spacerItem5)
        self.verticalLayout_4.addLayout(self.horizontalLayout_8)
        self.verticalLayout_2 = QtWidgets.QVBoxLayout()
        self.verticalLayout_2.setSpacing(5)
        self.verticalLayout_2.setObjectName("verticalLayout_2")
        self.horizontalLayout_2 = QtWidgets.QHBoxLayout()
        self.horizontalLayout_2.setSpacing(0)
        self.horizontalLayout_2.setObjectName("horizontalLayout_2")
        spacerItem6 = QtWidgets.QSpacerItem(13, 177, QtWidgets.QSizePolicy.Policy.Expanding,
                                            QtWidgets.QSizePolicy.Policy.Minimum)
        self.horizontalLayout_2.addItem(spacerItem6)
        self.weather24hour = QtWidgets.QFrame(parent=self.frame_4)
        self.weather24hour.setMinimumSize(QtCore.QSize(465, 180))
        self.weather24hour.setMaximumSize(QtCore.QSize(465, 180))
        self.weather24hour.setContextMenuPolicy(QtCore.Qt.ContextMenuPolicy.DefaultContextMenu)
        self.weather24hour.setLayoutDirection(QtCore.Qt.LayoutDirection.LeftToRight)
        self.weather24hour.setStyleSheet("QFrame#weather24hour{    \n"
                                         "\n"
                                         "    border-radius: 10px; /* 设置圆角半径为 10 像素,可以根据需要调整 */\n"
                                         "    background-color: rgb(248, 242, 229);\n"
                                         "}\n"
                                         "\n"
                                         "QScrollArea{\n"
                                         "font: 12pt \"MiSans Normal\";\n"
                                         "color: rgb(93, 93, 93);\n"
                                         "\n"
                                         "}\n"
                                         "\n"
                                         "")
        self.weather24hour.setFrameShape(QtWidgets.QFrame.Shape.StyledPanel)
        self.weather24hour.setFrameShadow(QtWidgets.QFrame.Shadow.Raised)
        self.weather24hour.setObjectName("weather24hour")
        self.verticalLayout_3 = QtWidgets.QVBoxLayout(self.weather24hour)
        self.verticalLayout_3.setContentsMargins(0, 0, 0, 0)
        self.verticalLayout_3.setSpacing(0)
        self.verticalLayout_3.setObjectName("verticalLayout_3")
        self.frame_3 = QtWidgets.QFrame(parent=self.weather24hour)
        self.frame_3.setMinimumSize(QtCore.QSize(0, 30))
        self.frame_3.setStyleSheet("font: 9pt \"MiSans\";\n"
                                   "color: rgb(93, 93, 93);")
        self.frame_3.setFrameShape(QtWidgets.QFrame.Shape.StyledPanel)
        self.frame_3.setFrameShadow(QtWidgets.QFrame.Shadow.Raised)
        self.frame_3.setObjectName("frame_3")
        self.horizontalLayout_4 = QtWidgets.QHBoxLayout(self.frame_3)
        self.horizontalLayout_4.setContentsMargins(10, 0, 10, 0)
        self.horizontalLayout_4.setSpacing(5)
        self.horizontalLayout_4.setObjectName("horizontalLayout_4")
        self.label = QtWidgets.QLabel(parent=self.frame_3)
        self.label.setMinimumSize(QtCore.QSize(0, 30))
        self.label.setMaximumSize(QtCore.QSize(16777215, 30))
        font = QtGui.QFont()
        font.setFamily("MiSans Normal")
        font.setPointSize(12)
        font.setBold(False)
        font.setItalic(False)
        font.setWeight(50)
        self.label.setFont(font)
        self.label.setStyleSheet("font: 12pt \"MiSans Normal\";")
        self.label.setObjectName("label")
        self.horizontalLayout_4.addWidget(self.label)
        spacerItem7 = QtWidgets.QSpacerItem(30, 20, QtWidgets.QSizePolicy.Policy.Expanding,
                                            QtWidgets.QSizePolicy.Policy.Minimum)
        self.horizontalLayout_4.addItem(spacerItem7)
        self.sunriseicon = QtWidgets.QLabel(parent=self.frame_3)
        self.sunriseicon.setMinimumSize(QtCore.QSize(30, 30))
        self.sunriseicon.setMaximumSize(QtCore.QSize(16777215, 30))
        self.sunriseicon.setStyleSheet("image: url(res/wicon/0 (1).webp);")
        self.sunriseicon.setText("")
        self.sunriseicon.setAlignment(QtCore.Qt.AlignmentFlag.AlignCenter)
        self.sunriseicon.setObjectName("sunriseicon")
        self.horizontalLayout_4.addWidget(self.sunriseicon)
        self.sunrise = QtWidgets.QLabel(parent=self.frame_3)
        self.sunrise.setMinimumSize(QtCore.QSize(40, 30))
        self.sunrise.setMaximumSize(QtCore.QSize(16777215, 30))
        self.sunrise.setAlignment(QtCore.Qt.AlignmentFlag.AlignCenter)
        self.sunrise.setObjectName("sunrise")
        self.horizontalLayout_4.addWidget(self.sunrise)
        self.sunseticon = QtWidgets.QLabel(parent=self.frame_3)
        self.sunseticon.setMinimumSize(QtCore.QSize(30, 30))
        self.sunseticon.setMaximumSize(QtCore.QSize(16777215, 30))
        self.sunseticon.setStyleSheet("image: url(res/wicon/0.webp);")
        self.sunseticon.setText("")
        self.sunseticon.setObjectName("sunseticon")
        self.horizontalLayout_4.addWidget(self.sunseticon)
        self.sunset = QtWidgets.QLabel(parent=self.frame_3)
        self.sunset.setMinimumSize(QtCore.QSize(40, 30))
        self.sunset.setMaximumSize(QtCore.QSize(16777215, 30))
        self.sunset.setAlignment(QtCore.Qt.AlignmentFlag.AlignCenter)
        self.sunset.setObjectName("sunset")
        self.horizontalLayout_4.addWidget(self.sunset)
        self.verticalLayout_3.addWidget(self.frame_3)
        self.hour24 = QtWidgets.QScrollArea(parent=self.weather24hour)
        self.hour24.setStyleSheet("color: rgb(93, 93, 93);\n"
                                  "    border: none;")
        self.hour24.setWidgetResizable(True)
        self.hour24.setAlignment(QtCore.Qt.AlignmentFlag.AlignCenter)
        self.hour24.setObjectName("hour24")
        self.scrollAreaWidgetContents_4 = QtWidgets.QWidget()
        self.scrollAreaWidgetContents_4.setGeometry(QtCore.QRect(0, 0, 465, 148))
        self.scrollAreaWidgetContents_4.setStyleSheet("\n"
                                                      "    background-color: rgb(248, 242, 229);")
        self.scrollAreaWidgetContents_4.setObjectName("scrollAreaWidgetContents_4")
        self.horizontalLayout_7 = QtWidgets.QHBoxLayout(self.scrollAreaWidgetContents_4)
        self.horizontalLayout_7.setObjectName("horizontalLayout_7")
        self.hour24.setWidget(self.scrollAreaWidgetContents_4)
        self.verticalLayout_3.addWidget(self.hour24)
        self.horizontalLayout_2.addWidget(self.weather24hour)
        spacerItem8 = QtWidgets.QSpacerItem(13, 177, QtWidgets.QSizePolicy.Policy.Expanding,
                                            QtWidgets.QSizePolicy.Policy.Minimum)
        self.horizontalLayout_2.addItem(spacerItem8)
        self.verticalLayout_2.addLayout(self.horizontalLayout_2)
        self.horizontalLayout_6 = QtWidgets.QHBoxLayout()
        self.horizontalLayout_6.setContentsMargins(-1, -1, -1, 10)
        self.horizontalLayout_6.setSpacing(0)
        self.horizontalLayout_6.setObjectName("horizontalLayout_6")
        spacerItem9 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Policy.Expanding,
                                            QtWidgets.QSizePolicy.Policy.Minimum)
        self.horizontalLayout_6.addItem(spacerItem9)
        self.frame = QtWidgets.QFrame(parent=self.frame_4)
        self.frame.setMinimumSize(QtCore.QSize(465, 300))
        self.frame.setStyleSheet("    border-bottom-left-radius:15px;\n"
                                 "border-bottom-right-radius:15px;\n"
                                 "    background-color: rgb(248, 242, 229);")
        self.frame.setFrameShape(QtWidgets.QFrame.Shape.StyledPanel)
        self.frame.setFrameShadow(QtWidgets.QFrame.Shadow.Raised)
        self.frame.setObjectName("frame")
        self.horizontalLayout_12 = QtWidgets.QHBoxLayout(self.frame)
        self.horizontalLayout_12.setContentsMargins(0, 0, 0, 13)
        self.horizontalLayout_12.setSpacing(0)
        self.horizontalLayout_12.setObjectName("horizontalLayout_12")
        self.scrollArea = QtWidgets.QScrollArea(parent=self.frame)
        self.scrollArea.setStyleSheet("QScrollArea{\n"
                                      "font: 12pt \"MiSans Normal\";\n"
                                      "color: rgb(93, 93, 93);\n"
                                      "\n"
                                      "}\n"
                                      "\n"
                                      "\n"
                                      "QScrollArea QScrollBar:vertical {\n"
                                      "    background: rgba(255, 255, 255, 0);\n"
                                      "    width: 10px;\n"
                                      "    margin: 50px 0px 50px 0px;\n"
                                      "}\n"
                                      "QScrollArea QScrollBar::handle:vertical {\n"
                                      "    background: rgba(0, 170, 127,150);\n"
                                      "    min-height: 10px;\n"
                                      "    border-radius: 5px; /* 设置圆角半径为 10 像素,可以根据需要调整 */\n"
                                      "\n"
                                      "\n"
                                      "}\n"
                                      "QScrollArea QScrollBar::add-line:vertical {\n"
                                      "    background: none;\n"
                                      "    height: 0px;\n"
                                      "    subcontrol-position: bottom;\n"
                                      "    subcontrol-origin: margin;\n"
                                      "}\n"
                                      "QScrollArea QScrollBar::sub-line:vertical {\n"
                                      "    background: none;\n"
                                      "    height: 0px;\n"
                                      "    subcontrol-position: top;\n"
                                      "    subcontrol-origin: margin;\n"
                                      "}")
        self.scrollArea.setWidgetResizable(True)
        self.scrollArea.setAlignment(QtCore.Qt.AlignmentFlag.AlignCenter)
        self.scrollArea.setObjectName("scrollArea")
        self.scrollAreaWidgetContents = QtWidgets.QWidget()
        self.scrollAreaWidgetContents.setGeometry(QtCore.QRect(0, 0, 455, 560))
        self.scrollAreaWidgetContents.setObjectName("scrollAreaWidgetContents")
        self.verticalLayout_5 = QtWidgets.QVBoxLayout(self.scrollAreaWidgetContents)
        self.verticalLayout_5.setObjectName("verticalLayout_5")
        self.frame_2 = QtWidgets.QFrame(parent=self.scrollAreaWidgetContents)
        self.frame_2.setMinimumSize(QtCore.QSize(0, 30))
        self.frame_2.setMaximumSize(QtCore.QSize(16777215, 30))
        self.frame_2.setFrameShape(QtWidgets.QFrame.Shape.StyledPanel)
        self.frame_2.setFrameShadow(QtWidgets.QFrame.Shadow.Raised)
        self.frame_2.setObjectName("frame_2")
        self.horizontalLayout_11 = QtWidgets.QHBoxLayout(self.frame_2)
        self.horizontalLayout_11.setContentsMargins(0, 0, 0, 0)
        self.horizontalLayout_11.setSpacing(0)
        self.horizontalLayout_11.setObjectName("horizontalLayout_11")
        self.label_2 = QtWidgets.QLabel(parent=self.frame_2)
        self.label_2.setMinimumSize(QtCore.QSize(0, 30))
        self.label_2.setMaximumSize(QtCore.QSize(16777215, 30))
        font = QtGui.QFont()
        font.setFamily("MiSans Normal")
        font.setPointSize(12)
        font.setBold(False)
        font.setItalic(False)
        font.setWeight(50)
        self.label_2.setFont(font)
        self.label_2.setStyleSheet("font: 12pt \"MiSans Normal\";\n"
                                   "color: rgb(93, 93, 93);")
        self.label_2.setObjectName("label_2")
        self.horizontalLayout_11.addWidget(self.label_2)
        spacerItem10 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Policy.Expanding,
                                             QtWidgets.QSizePolicy.Policy.Minimum)
        self.horizontalLayout_11.addItem(spacerItem10)
        self.label_6 = QtWidgets.QLabel(parent=self.frame_2)
        self.label_6.setMinimumSize(QtCore.QSize(30, 30))
        self.label_6.setStyleSheet("image: url(res/loginicon/icon_Lan64/unfold.png);")
        self.label_6.setText("")
        self.label_6.setObjectName("label_6")
        self.horizontalLayout_11.addWidget(self.label_6)
        self.verticalLayout_5.addWidget(self.frame_2)
        self.line_2 = QtWidgets.QFrame(parent=self.scrollAreaWidgetContents)
        self.line_2.setMinimumSize(QtCore.QSize(0, 1))
        self.line_2.setStyleSheet("background-color: rgb(93, 93, 93);")
        self.line_2.setFrameShape(QtWidgets.QFrame.Shape.HLine)
        self.line_2.setFrameShadow(QtWidgets.QFrame.Shadow.Sunken)
        self.line_2.setObjectName("line_2")
        self.verticalLayout_5.addWidget(self.line_2)
        self.scrollArea_2 = QtWidgets.QScrollArea(parent=self.scrollAreaWidgetContents)
        self.scrollArea_2.setMinimumSize(QtCore.QSize(0, 250))
        self.scrollArea_2.setMaximumSize(QtCore.QSize(16777215, 230))
        self.scrollArea_2.setWidgetResizable(True)
        self.scrollArea_2.setAlignment(QtCore.Qt.AlignmentFlag.AlignCenter)
        self.scrollArea_2.setObjectName("scrollArea_2")
        self.scrollAreaWidgetContents_2 = QtWidgets.QWidget()
        self.scrollAreaWidgetContents_2.setGeometry(QtCore.QRect(0, 0, 437, 250))
        self.scrollAreaWidgetContents_2.setObjectName("scrollAreaWidgetContents_2")
        self.horizontalLayout_9 = QtWidgets.QHBoxLayout(self.scrollAreaWidgetContents_2)
        self.horizontalLayout_9.setObjectName("horizontalLayout_9")
        self.scrollArea_2.setWidget(self.scrollAreaWidgetContents_2)
        self.verticalLayout_5.addWidget(self.scrollArea_2)
        self.frame_5 = QtWidgets.QFrame(parent=self.scrollAreaWidgetContents)
        self.frame_5.setMinimumSize(QtCore.QSize(0, 30))
        self.frame_5.setFrameShape(QtWidgets.QFrame.Shape.StyledPanel)
        self.frame_5.setFrameShadow(QtWidgets.QFrame.Shadow.Raised)
        self.frame_5.setObjectName("frame_5")
        self.horizontalLayout_10 = QtWidgets.QHBoxLayout(self.frame_5)
        self.horizontalLayout_10.setContentsMargins(0, 0, 0, 0)
        self.horizontalLayout_10.setSpacing(0)
        self.horizontalLayout_10.setObjectName("horizontalLayout_10")
        self.label_3 = QtWidgets.QLabel(parent=self.frame_5)
        self.label_3.setMinimumSize(QtCore.QSize(0, 30))
        self.label_3.setMaximumSize(QtCore.QSize(16777215, 30))
        font = QtGui.QFont()
        font.setFamily("MiSans Normal")
        font.setPointSize(12)
        font.setBold(False)
        font.setItalic(False)
        font.setWeight(50)
        self.label_3.setFont(font)
        self.label_3.setStyleSheet("font: 12pt \"MiSans Normal\";")
        self.label_3.setObjectName("label_3")
        self.horizontalLayout_10.addWidget(self.label_3)
        spacerItem11 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Policy.Expanding,
                                             QtWidgets.QSizePolicy.Policy.Minimum)
        self.horizontalLayout_10.addItem(spacerItem11)
        self.label_7 = QtWidgets.QLabel(parent=self.frame_5)
        self.label_7.setMinimumSize(QtCore.QSize(30, 30))
        self.label_7.setStyleSheet("image: url(res/loginicon/icon_Lan64/top.png);")
        self.label_7.setText("")
        self.label_7.setObjectName("label_7")
        self.horizontalLayout_10.addWidget(self.label_7)
        self.verticalLayout_5.addWidget(self.frame_5)
        self.line = QtWidgets.QFrame(parent=self.scrollAreaWidgetContents)
        self.line.setMinimumSize(QtCore.QSize(0, 1))
        self.line.setStyleSheet("background-color: rgb(93, 93, 93);\n"
                                "border:1px;")
        self.line.setFrameShape(QtWidgets.QFrame.Shape.HLine)
        self.line.setFrameShadow(QtWidgets.QFrame.Shadow.Sunken)
        self.line.setObjectName("line")
        self.verticalLayout_5.addWidget(self.line)
        self.frame_6 = QtWidgets.QFrame(parent=self.scrollAreaWidgetContents)
        self.frame_6.setMinimumSize(QtCore.QSize(0, 200))
        self.frame_6.setFrameShape(QtWidgets.QFrame.Shape.StyledPanel)
        self.frame_6.setFrameShadow(QtWidgets.QFrame.Shadow.Raised)
        self.frame_6.setObjectName("frame_6")
        self.gridLayout = QtWidgets.QGridLayout(self.frame_6)
        self.gridLayout.setObjectName("gridLayout")
        self.verticalLayout_14 = QtWidgets.QVBoxLayout()
        self.verticalLayout_14.setContentsMargins(3, 3, 3, 3)
        self.verticalLayout_14.setSpacing(0)
        self.verticalLayout_14.setObjectName("verticalLayout_14")
        self.label_39 = QtWidgets.QLabel(parent=self.frame_6)
        self.label_39.setMinimumSize(QtCore.QSize(60, 60))
        self.label_39.setStyleSheet("image: url(res/wicon/20dd13b486c4943d3df0f295cc58a153.png);")
        self.label_39.setText("")
        self.label_39.setObjectName("label_39")
        self.verticalLayout_14.addWidget(self.label_39)
        self.level_1 = QtWidgets.QLabel(parent=self.frame_6)
        self.level_1.setAlignment(QtCore.Qt.AlignmentFlag.AlignCenter)
        self.level_1.setObjectName("level_1")
        self.verticalLayout_14.addWidget(self.level_1)
        self.gridLayout.addLayout(self.verticalLayout_14, 1, 0, 1, 1)
        self.verticalLayout_39 = QtWidgets.QVBoxLayout()
        self.verticalLayout_39.setContentsMargins(3, 3, 3, 3)
        self.verticalLayout_39.setSpacing(0)
        self.verticalLayout_39.setObjectName("verticalLayout_39")
        self.label_114 = QtWidgets.QLabel(parent=self.frame_6)
        self.label_114.setMinimumSize(QtCore.QSize(60, 60))
        self.label_114.setStyleSheet("image: url(res/wicon/13c92a56c6176983cf3554a6586b797e.png);")
        self.label_114.setText("")
        self.label_114.setObjectName("label_114")
        self.verticalLayout_39.addWidget(self.label_114)
        self.level_3 = QtWidgets.QLabel(parent=self.frame_6)
        self.level_3.setAlignment(QtCore.Qt.AlignmentFlag.AlignCenter)
        self.level_3.setObjectName("level_3")
        self.verticalLayout_39.addWidget(self.level_3)
        self.gridLayout.addLayout(self.verticalLayout_39, 1, 2, 1, 1)
        self.verticalLayout_16 = QtWidgets.QVBoxLayout()
        self.verticalLayout_16.setContentsMargins(3, 3, 3, 3)
        self.verticalLayout_16.setSpacing(0)
        self.verticalLayout_16.setObjectName("verticalLayout_16")
        self.label_45 = QtWidgets.QLabel(parent=self.frame_6)
        self.label_45.setMinimumSize(QtCore.QSize(60, 60))
        self.label_45.setStyleSheet("\n"
                                    "image: url(res/wicon/allergy.png);")
        self.label_45.setText("")
        self.label_45.setObjectName("label_45")
        self.verticalLayout_16.addWidget(self.label_45)
        self.level_4 = QtWidgets.QLabel(parent=self.frame_6)
        self.level_4.setAlignment(QtCore.Qt.AlignmentFlag.AlignCenter)
        self.level_4.setObjectName("level_4")
        self.verticalLayout_16.addWidget(self.level_4)
        self.gridLayout.addLayout(self.verticalLayout_16, 1, 3, 1, 1)
        self.verticalLayout_22 = QtWidgets.QVBoxLayout()
        self.verticalLayout_22.setContentsMargins(3, 3, 3, 3)
        self.verticalLayout_22.setSpacing(0)
        self.verticalLayout_22.setObjectName("verticalLayout_22")
        self.label_63 = QtWidgets.QLabel(parent=self.frame_6)
        self.label_63.setMinimumSize(QtCore.QSize(60, 60))
        self.label_63.setStyleSheet("image: url(res/wicon/sports.png);")
        self.label_63.setText("")
        self.label_63.setObjectName("label_63")
        self.verticalLayout_22.addWidget(self.label_63)
        self.level_6 = QtWidgets.QLabel(parent=self.frame_6)
        self.level_6.setAlignment(QtCore.Qt.AlignmentFlag.AlignCenter)
        self.level_6.setObjectName("level_6")
        self.verticalLayout_22.addWidget(self.level_6)
        self.gridLayout.addLayout(self.verticalLayout_22, 2, 1, 1, 1)
        self.verticalLayout_21 = QtWidgets.QVBoxLayout()
        self.verticalLayout_21.setContentsMargins(3, 3, 3, 3)
        self.verticalLayout_21.setSpacing(0)
        self.verticalLayout_21.setObjectName("verticalLayout_21")
        self.label_60 = QtWidgets.QLabel(parent=self.frame_6)
        self.label_60.setMinimumSize(QtCore.QSize(60, 60))
        self.label_60.setStyleSheet("image: url(res/wicon/0df4a9e43dcea8ba17cddefb18105cd5.png);\n"
                                    "image: url(res/wicon/98407003636bd16bca455ea6fc7bdc97.png);")
        self.label_60.setText("")
        self.label_60.setObjectName("label_60")
        self.verticalLayout_21.addWidget(self.label_60)
        self.level_2 = QtWidgets.QLabel(parent=self.frame_6)
        self.level_2.setAlignment(QtCore.Qt.AlignmentFlag.AlignCenter)
        self.level_2.setObjectName("level_2")
        self.verticalLayout_21.addWidget(self.level_2)
        self.gridLayout.addLayout(self.verticalLayout_21, 1, 1, 1, 1)
        self.verticalLayout_23 = QtWidgets.QVBoxLayout()
        self.verticalLayout_23.setContentsMargins(3, 3, 3, 3)
        self.verticalLayout_23.setSpacing(0)
        self.verticalLayout_23.setObjectName("verticalLayout_23")
        self.label_66 = QtWidgets.QLabel(parent=self.frame_6)
        self.label_66.setMinimumSize(QtCore.QSize(60, 60))
        self.label_66.setStyleSheet("image: url(res/wicon/4fc1b9c1ee59ed6a3e5a05017fc9360b.png);")
        self.label_66.setText("")
        self.label_66.setObjectName("label_66")
        self.verticalLayout_23.addWidget(self.label_66)
        self.level_5 = QtWidgets.QLabel(parent=self.frame_6)
        self.level_5.setAlignment(QtCore.Qt.AlignmentFlag.AlignCenter)
        self.level_5.setObjectName("level_5")
        self.verticalLayout_23.addWidget(self.level_5)
        self.gridLayout.addLayout(self.verticalLayout_23, 2, 0, 1, 1)
        self.verticalLayout_24 = QtWidgets.QVBoxLayout()
        self.verticalLayout_24.setContentsMargins(3, 3, 3, 3)
        self.verticalLayout_24.setSpacing(0)
        self.verticalLayout_24.setObjectName("verticalLayout_24")
        self.label_64 = QtWidgets.QLabel(parent=self.frame_6)
        self.label_64.setMinimumSize(QtCore.QSize(60, 60))
        self.label_64.setStyleSheet("image: url(res/wicon/sports.png);")
        self.label_64.setText("")
        self.label_64.setObjectName("label_64")
        self.verticalLayout_24.addWidget(self.label_64)
        self.level_7 = QtWidgets.QLabel(parent=self.frame_6)
        self.level_7.setAlignment(QtCore.Qt.AlignmentFlag.AlignCenter)
        self.level_7.setObjectName("level_7")
        self.verticalLayout_24.addWidget(self.level_7)
        self.gridLayout.addLayout(self.verticalLayout_24, 2, 2, 1, 1)
        self.verticalLayout_25 = QtWidgets.QVBoxLayout()
        self.verticalLayout_25.setContentsMargins(3, 3, 3, 3)
        self.verticalLayout_25.setSpacing(0)
        self.verticalLayout_25.setObjectName("verticalLayout_25")
        self.label_69 = QtWidgets.QLabel(parent=self.frame_6)
        self.label_69.setMinimumSize(QtCore.QSize(60, 60))
        self.label_69.setStyleSheet("image: url(res/wicon/sports.png);")
        self.label_69.setText("")
        self.label_69.setObjectName("label_69")
        self.verticalLayout_25.addWidget(self.label_69)
        self.level_8 = QtWidgets.QLabel(parent=self.frame_6)
        self.level_8.setAlignment(QtCore.Qt.AlignmentFlag.AlignCenter)
        self.level_8.setObjectName("level_8")
        self.verticalLayout_25.addWidget(self.level_8)
        self.gridLayout.addLayout(self.verticalLayout_25, 2, 3, 1, 1)
        self.verticalLayout_5.addWidget(self.frame_6)
        self.scrollArea.setWidget(self.scrollAreaWidgetContents)
        self.horizontalLayout_12.addWidget(self.scrollArea)
        self.horizontalLayout_6.addWidget(self.frame)
        spacerItem12 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Policy.Expanding,
                                             QtWidgets.QSizePolicy.Policy.Minimum)
        self.horizontalLayout_6.addItem(spacerItem12)
        self.verticalLayout_2.addLayout(self.horizontalLayout_6)
        self.verticalLayout_4.addLayout(self.verticalLayout_2)
        self.horizontalLayout_5.addWidget(self.frame_4)

        self.retranslateUi(weatherUIForm)
        QtCore.QMetaObject.connectSlotsByName(weatherUIForm)

    def retranslateUi(self, weatherUIForm):
        _translate = QtCore.QCoreApplication.translate
        weatherUIForm.setWindowTitle(_translate("weatherUIForm", "Form"))
        self.temp.setText(_translate("weatherUIForm", "28°"))
        self.aqi.setText(_translate("weatherUIForm", "空气 优"))
        self.feelsLike.setText(_translate("weatherUIForm", "体感27°"))
        self.text.setText(_translate("weatherUIForm", "多云转晴天"))
        self.windDir.setText(_translate("weatherUIForm", "东北风5~6级"))
        self.label_4.setText(_translate("weatherUIForm", "杭州"))
        self.label.setText(_translate("weatherUIForm", "24小时预报"))
        self.sunrise.setText(_translate("weatherUIForm", "6:47"))
        self.sunset.setText(_translate("weatherUIForm", "18:14"))
        self.label_2.setText(_translate("weatherUIForm", "7天预报"))
        self.label_3.setText(_translate("weatherUIForm", "生活指数"))
        self.level_1.setText(_translate("weatherUIForm", "level"))
        self.level_3.setText(_translate("weatherUIForm", "level"))
        self.level_4.setText(_translate("weatherUIForm", "level"))
        self.level_6.setText(_translate("weatherUIForm", "level"))
        self.level_2.setText(_translate("weatherUIForm", "level"))
        self.level_5.setText(_translate("weatherUIForm", "level"))
        self.level_7.setText(_translate("weatherUIForm", "level"))
        self.level_8.setText(_translate("weatherUIForm", "level"))

第三步,图标字体和映射代码处理,用来处理天气图标

首先要接收天气图标代码,然后返回对应Unicode字符

import re

class IconParser:
    def __init__(self, css_file_path):
        self.css_file_path = css_file_path
        self.icon_map = {}

    def load_icon_map(self):
        """ 从CSS文件中加载图标代码到Unicode字符的映射 """
        with open(self.css_file_path, 'r', encoding='utf-8') as file:
            css_content = file.read()
            pattern = r'\.qi-(\d+)\s*::before\s*{\s*content:\s*"\\([f\d]+)"\s*;\s*}'
            matches = re.findall(pattern, css_content)
            for icon_code, unicode_char in matches:
                # 使用 chr() 函数将 Unicode 字符代码转换为实际的 Unicode 字符
                self.icon_map[icon_code] = chr(int(unicode_char, 16))

    def get_icon_map(self):
        """ 返回图标映射字典 """
        return self.icon_map

第四步,整合程序

from pprint import pprint

from PyQt6 import QtCore, QtGui, QtWidgets
from PyQt6.QtCore import Qt
from PyQt6.QtGui import QPalette, QFont, QFontDatabase
from PyQt6.QtWidgets import QWidget

from WeatherAPI.weather_module import WeatherAPI
from UIclass.WeatherMainUI import Ui_weatherUIForm
from UIclass.BorderlessWindow import CustomWindow
import sys

# 导入IconParser类,解析和风天气图标代码
from UIclass.fontClass.Fonticon import IconParser


class WeatherUI(CustomWindow):
    def __init__(self, city_name, api_key):
        super().__init__()
        self.ui = Ui_weatherUIForm()
        self.ui.setupUi(self)
        self.city_name = city_name
        self.api_key = api_key

        # 设置城市名称
        self.ui.label_4.setText(city_name)

        # 创建 IconParser 实例并加载图标映射
        self.icon_parser = IconParser("UIclass/fontClass/qweather-icons.css")
        self.icon_parser.load_icon_map()
        self.icon_map = self.icon_parser.get_icon_map()  # 确保赋值给 self


        # 注册字体
        font_id = QFontDatabase.addApplicationFont("UIclass/fontClass/qweather-icons.ttf")
        self.families = QFontDatabase.applicationFontFamilies(font_id)
        font_family = self.families[0]

        # 设置实时天气图标字体
        icon_font = QFont(font_family)
        icon_font.setPointSize(80)  # 尝试不同的字体大小
        self.ui.icon.setFont(icon_font)  # 实时天气图标设置字体

        # 创建小时天气图标 QLabel
        self.ui.hour_icon = QtWidgets.QLabel(self.ui.hour24)
        self.ui.hour_icon.setFont(icon_font)  # 设置小时图标字体
        self.ui.hour_icon.setFixedSize(50, 50)  # 设置固定大小

        # 设置图标大小
        self.ui.icon.setFixedSize(150, 150)  # 设置固定大小

        # 设置字体颜色
        palette = QPalette()
        palette.setColor(QPalette.ColorRole.Text, Qt.GlobalColor.white)
        self.ui.icon.setPalette(palette)
        self.ui.hour_icon.setPalette(palette)

        # 初始化UI上的文本
        self.initialize_ui_text()

        # 获取天气数据并更新 UI
        self.update_weather_data()

        # 连接按钮点击事件
        self.ui.pushButton.clicked.connect(self.on_button_clicked)
        self.ui.clockbut.clicked.connect(self.close_window)

    def close_window(self):
        self.close()

    def initialize_ui_text(self):
        self.ui.temp.setText("Loading...")
        self.ui.aqi.setText("Loading...")
        self.ui.feelsLike.setText("Loading...")
        self.ui.text.setText("Loading...")
        self.ui.windDir.setText("Loading...")
        self.ui.icon.setText("\uf20b")  # 设置默认图标
        self.ui.windDir.setText("Loading...")
        self.ui.sunset.setText("Loading...")
        self.ui.sunrise.setText("Loading...")
        self.ui.sunrise.setText("Loading...")
        self.ui.sunset.setText("Loading...")

    def on_button_clicked(self):
        # 获取输入的城市名称
        self.city_name = self.ui.lineEdit.text()
        # 更新 label_4 的文本
        self.ui.label_4.setText(self.city_name)
        # 更新UI
        self.update_weather_data()

    def update_weather_data(self):
        weather_api = WeatherAPI(self.api_key)
        weather_data = weather_api.get_weather_data_by_city_name(self.city_name, [
            'realtime', 'air_quality', '24hour', 'sunrise_sunset', 'life_indices', 'future'])

        # 打印完整的 weather_data 结构以调试
        print("Full weather data:", weather_data)

        if "realtime" in weather_data:
            self.update_realtime_data(weather_data["realtime"])

        if "air_quality" in weather_data and "current" in weather_data["air_quality"]:
            self.update_air_quality_data(weather_data["air_quality"]["current"])

        if "24hour" in weather_data:
            self.update_hourly_data(weather_data["24hour"])

        if "sunrise_sunset" in weather_data and "sunrise_sunset" in weather_data["sunrise_sunset"]:
            self.update_sunrise_sunset_data(weather_data["sunrise_sunset"]["sunrise_sunset"])

        if "future" in weather_data:
            future_data = weather_data["future"]
            if isinstance(future_data, list):
                print("Future data:", future_data)  # 打印 future_data
                self.update_future_data(future_data)
            else:
                print("Future data is not a list:", future_data)

        if "life_indices" in weather_data:
            self.update_life_indices_data(weather_data["life_indices"])

    def update_realtime_data(self, realtime_data):
        self.ui.temp.setText(realtime_data.get("温度", "N/A"))
        self.ui.feelsLike.setText(f"体感 {realtime_data.get('体感温度', 'N/A')}")
        self.ui.text.setText(realtime_data.get("天气状况", "N/A"))
        wind_direction = realtime_data.get("风向", "N/A")
        wind_force = realtime_data.get("风力等级", "N/A")
        self.ui.windDir.setText(f"{wind_direction} {wind_force}级")
        icon_code = realtime_data.get("图标代码", "N/A")
        self.ui.icon.setText(self.icon_map.get(icon_code, "\uf153"))  # 使用默认图标

    def update_air_quality_data(self, aqi_data):
        self.ui.aqi.setText(f"空气 {aqi_data.get('空气质量指数', 'N/A')}")

    def update_hourly_data(self, hourly_data):
        # 清空现有的布局
        widget_contents = self.ui.hour24.widget()
        layout = widget_contents.layout()
        if layout is None:
            layout = QtWidgets.QVBoxLayout(widget_contents)
            widget_contents.setLayout(layout)

        self.clear_layout(layout)

        # 计算每行显示的 Weather24h 组件数量
        screen_width = self.screen().availableGeometry().width()
        num_widgets_per_row = screen_width // 50  # 假设每个组件宽度为50
        rows = (len(hourly_data) + num_widgets_per_row - 1) // num_widgets_per_row

        for row in range(rows):
            horizontal_layout = QtWidgets.QHBoxLayout()  # 新建一个水平布局
            for i in range(num_widgets_per_row):
                index = row * num_widgets_per_row + i
                if index < len(hourly_data):
                    # 创建新的控件
                    fx_time_label = QtWidgets.QLabel(widget_contents)
                    fx_time_label.setAlignment(QtCore.Qt.AlignmentFlag.AlignCenter)
                    fx_time_label.setText(hourly_data[index].get("预报时间", "N/A"))

                    icon_label = QtWidgets.QLabel(widget_contents)
                    icon_label.setMinimumSize(QtCore.QSize(50, 50))
                    icon_label.setAlignment(QtCore.Qt.AlignmentFlag.AlignCenter)
                    icon_label.setFont(QtGui.QFont(self.families[0], pointSize=30))  # 设置小时图标字体
                    icon_code = hourly_data[index].get("图标", "N/A")
                    icon_label.setText(self.icon_map.get(icon_code, "\uf101"))  # 使用默认图标

                    temp_label = QtWidgets.QLabel(widget_contents)
                    temp_label.setAlignment(QtCore.Qt.AlignmentFlag.AlignCenter)
                    temp_label.setText(hourly_data[index].get("温度", "N/A"))

                    text_label = QtWidgets.QLabel(widget_contents)
                    text_label.setAlignment(QtCore.Qt.AlignmentFlag.AlignCenter)
                    text_label.setText(hourly_data[index].get("天气状况", "N/A"))

                    # 添加控件到垂直布局
                    vertical_layout = QtWidgets.QVBoxLayout()
                    vertical_layout.addWidget(fx_time_label)
                    vertical_layout.addWidget(icon_label)
                    vertical_layout.addWidget(temp_label)
                    vertical_layout.addWidget(text_label)

                    # 添加垂直布局到水平布局
                    horizontal_layout.addLayout(vertical_layout)

            # 添加水平布局到垂直布局
            layout.addLayout(horizontal_layout)

        # 更新布局
        widget_contents.update()

    def clear_layout(self, layout):
        while layout.count():
            child = layout.takeAt(0)
            if child.widget():
                child.widget().deleteLater()

    def update_sunrise_sunset_data(self, sunrise_sunset_data):
        self.ui.sunrise.setText(sunrise_sunset_data.get("日出", "N/A"))
        self.ui.sunset.setText(sunrise_sunset_data.get("日落", "N/A"))

    def set_icon(self, icon_code):
        # 设置图标
        self.ui.icon.setText(self.icon_map.get(icon_code, "\uf153"))
        self.ui.icon.update()

    def update_life_indices_data(self, life_indices_data):
        # 假设UI界面上有8个QLabel控件,分别为:
        # level_1, level_2, ..., level_8
        labels = [getattr(self.ui, f"level_{i + 1}") for i in range(8)]

        # 遍历每个生活指数
        indices = life_indices_data.get("indices", {})
        for i, (category, index_info) in enumerate(indices.items()):
            if i < len(labels):
                label = labels[i]
                level = index_info.get("category", "N/A")
                label.setText(f"{level}")

    def update_future_data(self, future_data):
        future_contents = self.ui.scrollArea_2.widget()
        layout = future_contents.layout()
        if layout is None:
            layout = QtWidgets.QVBoxLayout(future_contents)
            future_contents.setLayout(layout)
        self.clear_layout(layout)

        # 动态计算每行显示的组件数量
        screen_width = self.screen().availableGeometry().width()
        num_widgets_per_row = max(1, screen_width // 100)  # 至少一个组件
        rows = (len(future_data) + num_widgets_per_row - 1) // num_widgets_per_row

        for row in range(rows):
            horizontal_layout = QtWidgets.QHBoxLayout()  # 新建一个水平布局
            for i in range(num_widgets_per_row):
                index = row * num_widgets_per_row + i
                if index < len(future_data):
                    # 创建新的控件
                    fx_date_label = QtWidgets.QLabel(future_contents)
                    fx_date_label.setAlignment(QtCore.Qt.AlignmentFlag.AlignCenter)
                    fx_date_label.setText(future_data[index].get("日期", "N/A"))

                    icon_day_label = QtWidgets.QLabel(future_contents)
                    icon_day_label.setMinimumSize(QtCore.QSize(50, 50))
                    icon_day_label.setAlignment(QtCore.Qt.AlignmentFlag.AlignCenter)
                    icon_day_label.setFont(QtGui.QFont(self.families[0], pointSize=30))  # 设置图标字体
                    icon_code = future_data[index].get("白天天气图标", "N/A")
                    icon_day_label.setText(self.icon_map.get(icon_code, "\uf153"))  # 使用默认图标

                    text_day_label = QtWidgets.QLabel(future_contents)
                    text_day_label.setAlignment(QtCore.Qt.AlignmentFlag.AlignCenter)
                    text_day_label.setText(future_data[index].get("白天天气", "N/A"))

                    temp_max_label = QtWidgets.QLabel(future_contents)
                    temp_max_label.setAlignment(QtCore.Qt.AlignmentFlag.AlignCenter)
                    temp_max_label.setText(future_data[index].get("最高温度", "N/A"))

                    temp_min_label = QtWidgets.QLabel(future_contents)
                    temp_min_label.setAlignment(QtCore.Qt.AlignmentFlag.AlignCenter)
                    temp_min_label.setText(future_data[index].get("最低温度", "N/A"))

                    icon_night_label = QtWidgets.QLabel(future_contents)
                    icon_night_label.setMinimumSize(QtCore.QSize(50, 50))
                    icon_night_label.setAlignment(QtCore.Qt.AlignmentFlag.AlignCenter)
                    icon_night_label.setFont(QtGui.QFont(self.families[0], pointSize=30))  # 设置图标字体
                    icon_code = future_data[index].get("夜间天气图标", "N/A")
                    icon_night_label.setText(self.icon_map.get(icon_code, "\uf153"))  # 使用默认图标

                    text_night_label = QtWidgets.QLabel(future_contents)
                    text_night_label.setAlignment(QtCore.Qt.AlignmentFlag.AlignCenter)
                    text_night_label.setText(future_data[index].get("夜间天气", "N/A"))

                    # 添加控件到垂直布局
                    vertical_layout = QtWidgets.QVBoxLayout()
                    vertical_layout.addWidget(fx_date_label)
                    vertical_layout.addWidget(icon_day_label)
                    vertical_layout.addWidget(text_day_label)
                    vertical_layout.addWidget(temp_max_label)
                    vertical_layout.addWidget(temp_min_label)
                    vertical_layout.addWidget(icon_night_label)
                    vertical_layout.addWidget(text_night_label)

                    # 添加垂直布局到水平布局
                    horizontal_layout.addLayout(vertical_layout)

            # 添加水平布局到垂直布局
            layout.addLayout(horizontal_layout)

        # 更新布局
        future_contents.update()


if __name__ == '__main__':
    city_name = input("请输入城市名称: ")
    api_key = "输入你的key,"
    app = QtWidgets.QApplication(sys.argv)
    weather_ui = WeatherUI(city_name, api_key)
    weather_ui.show()
    sys.exit(app.exec())

目前还有一个功能还没做,就是运行时自动显示所在地,

要使用PyQt获取城市天气预报,可以通过以下步骤实现: 1. 首先,需要获取天气数据。可以使用爬虫方式获取天气网站的HTML页面,然后使用解析库(如BeautifulSoup)解析内容。另一种方法是使用天气预报网站提供的API接口直接获取结构化的数据,省去了解析HTML的工作。在这个例子中,我们选择使用中国天气网站提供的API接口\[2\]。 2. 使用PyQt创建一个界面,用于显示天气预报信息。可以使用PyQt的各种控件来设计界面,如标签、文本框等。在这个例子中,我们可以创建一个标签用于显示城市名,一个标签用于显示温度,一个标签用于显示向等。 3. 在PyQt的主窗口类中,编写代码来获取天气数据并将其显示在界面上。可以使用requests库发送HTTP请求来获取天气数据\[3\]。然后,从返回的JSON数据中提取所需的天气信息,并将其设置到相应的标签中。 4. 最后,将界面文件转为.py文件,并调用主窗口类来显示界面。 通过以上步骤,我们可以实现一个使用PyQt获取城市天气预报的程序。 #### 引用[.reference_title] - *1* *3* [PyQt5快速开发与实战 10.1 获取城市天气预报](https://blog.csdn.net/weixin_44226181/article/details/126083561)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insert_down28v1,239^v3^insert_chatgpt"}} ] [.reference_item] - *2* [PyQt 5实战之城市天气预报](https://blog.csdn.net/qq_32019341/article/details/109564001)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insert_down28v1,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值