PyQt 5实战之城市天气预报

2023-09-24 14:16:11 浏览数 (2)

1.获取天气数据

使用python获取天气数据有很多种方法,其中一种是通过爬虫方式,获取天气网站的HTML页面,然后使用BeautifulSoup等解析内容,还有就是通过天气预报网站提供的API接口,直接获取结构化的数据,省去了解析HTML的工作。所以本利采用第二种方法,使用中国天气网站提供的API。 中国天气官网:中国天气

获取天气数据要使用Requests库,如果没有安装,请使用pip进行安装。 pip install requests 该库有一个名为json的方法,当请求的接口放回的是json格式的数据时,直接使用该方法访问即可,不需要再使用Python标准库中的json库了。

2.获取不同城市的天气预报API

请求地址是:http://www.weather.com.cn/data/sk/城市代码.html (该地址已失效) 请求地址是:http://wthrcdn.etouch.cn/weather_mini?citykey=101270101 (101270101 是城市代码) 部分城市代码如下,完整的城市代码可自行百度查询。

城市名

城市代码

北京

101010100

天津

101030100

上海

101020100

成都

101270101

部分返回参数列表如下:

名称

描述

data

消息根结点

city

城市中文名

wendu

温度

fengxiang

风向

fengli

风力中文

fengli

风力

date

日期

type

天气类型

在浏览器地址输入http://wthrcdn.etouch.cn/weather_mini?citykey=101270101这个请求地址,浏览器就会返回成都最近几天的天气实时情况,该信息就是一个json格式的字符串,格式化后如下:

代码语言:javascript复制
{
    "data":{
        "yesterday":{
            "date":"9日星期一",
            "high":"高温 23℃",
            "fx":"南风",
            "low":"低温 13℃",
            "fl":"<![CDATA[1级]]>",
            "type":"霾"
        },
        "city":"成都",
        "forecast":[
            {
                "date":"10日星期二",
                "high":"高温 21℃",
                "fengli":"<![CDATA[1级]]>",
                "low":"低温 15℃",
                "fengxiang":"东南风",
                "type":"多云"
            },
            {
                "date":"11日星期三",
                "high":"高温 20℃",
                "fengli":"<![CDATA[1级]]>",
                "low":"低温 15℃",
                "fengxiang":"东北风",
                "type":"多云"
            },
            {
                "date":"12日星期四",
                "high":"高温 20℃",
                "fengli":"<![CDATA[1级]]>",
                "low":"低温 15℃",
                "fengxiang":"东北风",
                "type":"多云"
            },
            {
                "date":"13日星期五",
                "high":"高温 19℃",
                "fengli":"<![CDATA[1级]]>",
                "low":"低温 14℃",
                "fengxiang":"东北风",
                "type":"阴"
            },
            {
                "date":"14日星期六",
                "high":"高温 19℃",
                "fengli":"<![CDATA[1级]]>",
                "low":"低温 14℃",
                "fengxiang":"东北风",
                "type":"阴"
            }
        ],
        "ganmao":"感冒低发期,天气舒适,请注意多吃蔬菜水果,多喝水哦。",
        "wendu":"20"
    },
    "status":1000,
    "desc":"OK"
}

示例代码:getWeatherInfo.py

代码语言:javascript复制
# -*- coding: utf-8 -*-

import requests

req = requests.get('http://wthrcdn.etouch.cn/weather_mini?citykey=101270101')
req.encoding = 'utf-8'

print('返回结果: %s' % req.json())
data = req.json()['data']
print('城市: %s' % data['city'])
today = req.json()['data']['forecast'][0]
print('日期: %s' % today['date'])
print('天气: %s' % today['type'])
print('风向: %s' % today['fengxiang'])
print('温度: %s' % data['wendu']   " °C")
print('最高温度: %s' % today['high'])
print('最低温度: %s' % today['low'])
print('风力: %s' % today['fengli'][-5:-3])
print('感冒指数: %s' % data['ganmao'])

以上代码请求API,可以获取到天气数据:

3.界面实现

使用Qt Designer来设计天气预报窗口,如下图:

添加信号和槽函数:

4.将界面转化为.py文件

使用pyuic5命令将界面转为.py文件,转换后的Python文件名是WeatherWin.py。 pyuic5 -o WeatherWin.py WeatherWin.ui

转换后的完整代码如下:

代码语言:javascript复制
# -*- coding: utf-8 -*-

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


from PyQt5 import QtCore, QtGui, QtWidgets


class Ui_Form(object):
    def setupUi(self, Form):
        Form.setObjectName("Form")
        Form.resize(465, 327)
        self.label = QtWidgets.QLabel(Form)
        self.label.setGeometry(QtCore.QRect(10, 0, 71, 31))
        self.label.setObjectName("label")
        self.label_2 = QtWidgets.QLabel(Form)
        self.label_2.setGeometry(QtCore.QRect(51, 41, 24, 16))
        self.label_2.setObjectName("label_2")
        self.weatherComboBox = QtWidgets.QComboBox(Form)
        self.weatherComboBox.setGeometry(QtCore.QRect(100, 40, 131, 20))
        self.weatherComboBox.setEditable(False)
        self.weatherComboBox.setObjectName("weatherComboBox")
        self.weatherComboBox.addItem("")
        self.weatherComboBox.addItem("")
        self.weatherComboBox.addItem("")
        self.weatherComboBox.addItem("")
        self.resultText = QtWidgets.QTextEdit(Form)
        self.resultText.setGeometry(QtCore.QRect(40, 70, 381, 181))
        self.resultText.setObjectName("resultText")
        self.queryBtn = QtWidgets.QPushButton(Form)
        self.queryBtn.setGeometry(QtCore.QRect(100, 280, 75, 23))
        self.queryBtn.setObjectName("queryBtn")
        self.clearBtn = QtWidgets.QPushButton(Form)
        self.clearBtn.setGeometry(QtCore.QRect(260, 280, 75, 23))
        self.clearBtn.setObjectName("clearBtn")

        self.retranslateUi(Form)
        self.queryBtn.clicked.connect(Form.queryWeather)
        self.clearBtn.clicked.connect(Form.clearResult)
        QtCore.QMetaObject.connectSlotsByName(Form)

    def retranslateUi(self, Form):
        _translate = QtCore.QCoreApplication.translate
        Form.setWindowTitle(_translate("Form", "Form"))
        self.label.setText(_translate("Form", "查询城市天气"))
        self.label_2.setText(_translate("Form", "城市"))
        self.weatherComboBox.setCurrentText(_translate("Form", "成都"))
        self.weatherComboBox.setItemText(0, _translate("Form", "成都"))
        self.weatherComboBox.setItemText(1, _translate("Form", "北京"))
        self.weatherComboBox.setItemText(2, _translate("Form", "上海"))
        self.weatherComboBox.setItemText(3, _translate("Form", "天津"))
        self.queryBtn.setText(_translate("Form", "查询"))
        self.clearBtn.setText(_translate("Form", "清空"))

5.调用主窗口类

在主窗口类MainWindow中调用界面类Ui_Form,然后在主窗口类中添加查询天气和清空结果的业务逻辑代码,这样就使界面显示和业务逻辑分离了。 本例文件名为CallWeatherWin.py,在主窗口类中定义了两个槽函数queryWeather()和clearResult(),以便在界面文件WeatherWin.ui中定义的两个按钮(queryBtn和clearBtn)触发clicked信号与这两个槽函数进行绑定。完整代码如下:

代码语言:javascript复制
# -*- coding: utf-8 -*-

import sys
from PyQt5.QtWidgets import QApplication, QMainWindow
from WeatherWin import Ui_Form
import requests


class MainWindow(QMainWindow):
    def __init__(self, parent=None):
        super(MainWindow, self).__init__(parent)
        self.ui = Ui_Form()
        self.ui.setupUi(self)

    def queryWeather(self):
        print('* queryWeather ')
        cityName = self.ui.weatherComboBox.currentText()
        cityCode = self.transCityName(cityName)

        req = requests.get('http://wthrcdn.etouch.cn/weather_mini?citykey='   cityCode)
        req.encoding = 'utf-8'
        print(req.json())
        data = req.json()['data']
        today = req.json()['data']['forecast'][0]
        msg1 = '城市: %s' % data['city']   'n'
        msg2 = '日期: %s' % today['date']   'n'
        msg3 = '天气: %s' % today['type']   'n'
        msg4 = '风向: %s' % today['fengxiang']   'n'
        msg5 = '温度: %s' % data['wendu']   " °C"   'n'
        msg6 = '最高温度: %s' % today['high']   'n'
        msg7 = '最低温度: %s' % today['low']   'n'
        msg8 = '风力: %s' % today['fengli'][-5:-3]   'n'
        msg9 = '感冒指数: %s' % data['ganmao']   'n'
        result = msg1   msg2   msg3   msg4   msg5   msg6   msg7   msg8   msg9
        self.ui.resultText.setText(result)

    def transCityName(self, cityName):
        cityCode = ''
        if cityName == '北京':
            cityCode = '101010100'
        elif cityName == '天津':
            cityCode = '101030100'
        elif cityName == '上海':
            cityCode = '101020100'
        elif cityName == '成都':
            cityCode = '101270101'

        return cityCode

    def clearResult(self):
        print('* clearResult ')
        self.ui.resultText.clear()


if __name__ == '__main__':
    app = QApplication(sys.argv)
    win = MainWindow()
    win.show()
    sys.exit(app.exec_())

效果图:

0 人点赞