[PyQt5 application example] obtain urban weather forecast

1, Get weather data

There are two ways to obtain weather data using Python: 1. Obtain the HTML page of the weather forecast website by crawling, and then parse the content of the HTML page by XPath or beautiful soup; 2. Through the API provided by the weather forecast website, the structured data can be obtained directly, eliminating the step of parsing HTML pages.
This example uses the API provided by China weather website. The address of China Weather official website is: http://www.weather.com.cn . The Requests library is used to obtain weather data. It is an HTTP library written in Python language based on urllib. It needs to be installed with pip command.

pip install requests

The Requests library contains a method called JSON. When the requested address returns data in JSON format, you can use this method directly instead of using the JSON Library in the Python standard library.

2, Get weather forecast API s for different cities

The request address is: http://www.weather.com.cn/data/sk/ City code. html, some city codes: Beijing 101010100, Shanghai 101020100. The complete city code can be found on the Internet( Codes of cities across the country).
The return parameters are shown in the following table.

namedescribe
weatherinfoweatherInfo message root node
cityChinese name of city
cityidCity ID
temptemperature
WDwind direction
WSwind power
SDhumidity
WSEwind power
timeRelease time
rainRain or not, 1: rain, 0: no rain
isRadarWhether there is a radar map, 1: there is a radar map, 0: there is no radar map
RadarRadar map number, radar map address: http://www.weather.com.cn/html/radar/ Radar chart no.shtml

Test code:

import requests


if __name__ == "__main__":
    rep = requests.get("http://www.weather.com.cn/data/sk/101020100.html")
    rep.encoding = "utf-8"

    print("Result: %s" % rep.json())
    print("City: %s" % rep.json()["weatherinfo"]["city"])
    print("Wind Direction: %s" % rep.json()["weatherinfo"]["WD"])
    print("Temperature: %s" % rep.json()["weatherinfo"]["temp"] + " °C")
    print("Wind Strength: %s" % rep.json()["weatherinfo"]["WS"])
    print("Humidity: %s" % rep.json()["weatherinfo"]["SD"])

Output results:

Result: {'weatherinfo': {'city': 'Shanghai', 'cityid': '101020100', 'temp': '23.5', 'WD': 'northeasterly wind', 'WS': 'Less than level 3', 'SD': '80%', 'AP': '1006.4hPa', 'njd': '2903', 'WSE': '<3', 'time': '17:00', 'sm': '1.1', 'isRadar': '1', 'Radar': 'JC_RADAR_AZ9210_JB'}}
City: Shanghai
Wind Direction: northeasterly wind
Temperature: 23.5 °C
Wind Strength: Less than level 3
Humidity: 80%

The business logic code for querying weather was debugged successfully.

3, Interface implementation

Use Qt Designer to design the weather forecast window, as shown in the following figure:

WeatherWin.ui Code:

<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
 <class>Form</class>
 <widget class="QWidget" name="Form">
  <property name="geometry">
   <rect>
    <x>0</x>
    <y>0</y>
    <width>450</width>
    <height>347</height>
   </rect>
  </property>
  <property name="windowTitle">
   <string>Form</string>
  </property>
  <widget class="QGroupBox" name="groupBox">
   <property name="geometry">
    <rect>
     <x>10</x>
     <y>10</y>
     <width>431</width>
     <height>251</height>
    </rect>
   </property>
   <property name="title">
    <string>Query City Weather</string>
   </property>
   <widget class="QComboBox" name="weatherComboBox">
    <property name="geometry">
     <rect>
      <x>80</x>
      <y>30</y>
      <width>221</width>
      <height>21</height>
     </rect>
    </property>
    <item>
     <property name="text">
      <string>Beijing</string>
     </property>
    </item>
    <item>
     <property name="text">
      <string>Tianjin</string>
     </property>
    </item>
    <item>
     <property name="text">
      <string>Shanghai</string>
     </property>
    </item>
   </widget>
   <widget class="QTextEdit" name="resultText">
    <property name="geometry">
     <rect>
      <x>10</x>
      <y>60</y>
      <width>411</width>
      <height>181</height>
     </rect>
    </property>
   </widget>
   <widget class="QLabel" name="label">
    <property name="geometry">
     <rect>
      <x>20</x>
      <y>30</y>
      <width>72</width>
      <height>21</height>
     </rect>
    </property>
    <property name="text">
     <string>city</string>
    </property>
   </widget>
  </widget>
  <widget class="QPushButton" name="queryBtn">
   <property name="geometry">
    <rect>
     <x>90</x>
     <y>300</y>
     <width>93</width>
     <height>28</height>
    </rect>
   </property>
   <property name="text">
    <string>query</string>
   </property>
  </widget>
  <widget class="QPushButton" name="clearBtn">
   <property name="geometry">
    <rect>
     <x>230</x>
     <y>300</y>
     <width>93</width>
     <height>28</height>
    </rect>
   </property>
   <property name="text">
    <string>empty</string>
   </property>
  </widget>
 </widget>
 <resources/>
 <connections>
  <connection>
   <sender>clearBtn</sender>
   <signal>clicked()</signal>
   <receiver>Form</receiver>
   <slot>clearResult()</slot>
   <hints>
    <hint type="sourcelabel">
     <x>270</x>
     <y>314</y>
    </hint>
    <hint type="destinationlabel">
     <x>363</x>
     <y>288</y>
    </hint>
   </hints>
  </connection>
  <connection>
   <sender>queryBtn</sender>
   <signal>clicked()</signal>
   <receiver>Form</receiver>
   <slot>queryWeather()</slot>
   <hints>
    <hint type="sourcelabel">
     <x>161</x>
     <y>313</y>
    </hint>
    <hint type="destinationlabel">
     <x>64</x>
     <y>286</y>
    </hint>
   </hints>
  </connection>
 </connections>
 <slots>
  <slot>clearResult()</slot>
  <slot>queryWeather()</slot>
 </slots>
</ui>

The control description is shown in the following table:

4, Convert interface files to. py files

Use the pyuic5 command to convert the interface file into a. Py file. The converted Python file name is WeatherWin.py.

pyuic5 -o WeatherWin.py WeatherWin.ui

The complete code of WeatherWin.py after conversion is as follows:

# -*- coding: utf-8 -*-

# Form implementation generated from reading ui file 'weather.ui'
#
# Created by: PyQt5 UI code generator 5.15.4
#
# 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(450, 347)
        self.groupBox = QtWidgets.QGroupBox(Form)
        self.groupBox.setGeometry(QtCore.QRect(10, 10, 431, 251))
        self.groupBox.setObjectName("groupBox")
        self.weatherComboBox = QtWidgets.QComboBox(self.groupBox)
        self.weatherComboBox.setGeometry(QtCore.QRect(80, 30, 221, 21))
        self.weatherComboBox.setObjectName("weatherComboBox")
        self.weatherComboBox.addItem("")
        self.weatherComboBox.addItem("")
        self.weatherComboBox.addItem("")
        self.resultText = QtWidgets.QTextEdit(self.groupBox)
        self.resultText.setGeometry(QtCore.QRect(10, 60, 411, 181))
        self.resultText.setObjectName("resultText")
        self.label = QtWidgets.QLabel(self.groupBox)
        self.label.setGeometry(QtCore.QRect(20, 30, 72, 21))
        self.label.setObjectName("label")
        self.queryBtn = QtWidgets.QPushButton(Form)
        self.queryBtn.setGeometry(QtCore.QRect(90, 300, 93, 28))
        self.queryBtn.setObjectName("queryBtn")
        self.clearBtn = QtWidgets.QPushButton(Form)
        self.clearBtn.setGeometry(QtCore.QRect(230, 300, 93, 28))
        self.clearBtn.setObjectName("clearBtn")

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

    def retranslateUi(self, Form):
        _translate = QtCore.QCoreApplication.translate
        Form.setWindowTitle(_translate("Form", "Form"))
        self.groupBox.setTitle(_translate("Form", "Query City Weather"))
        self.weatherComboBox.setItemText(0, _translate("Form", "Beijing"))
        self.weatherComboBox.setItemText(1, _translate("Form", "Tianjin"))
        self.weatherComboBox.setItemText(2, _translate("Form", "Shanghai"))
        self.label.setText(_translate("Form", "city"))
        self.queryBtn.setText(_translate("Form", "query"))
        self.clearBtn.setText(_translate("Form", "empty"))

5, Calling the main window class

In the main window class MainWindow, call the interface class Ui_Form, and add the business logic code to query the weather in the main window class, so that the interface display and business logic are separated.

# -*- 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)

		rep = requests.get('http://www.weather.com.cn/data/sk/' + cityCode + '.html')
		rep.encoding = 'utf-8'
		print( rep.json() ) 
		
		msg1 = 'city: %s' % rep.json()['weatherinfo']['city'] + '\n'
		msg2 = 'wind direction: %s' % rep.json()['weatherinfo']['WD'] + '\n'
		msg3 = 'temperature: %s' % rep.json()['weatherinfo']['temp'] + ' degree' + '\n'
		msg4 = 'wind power: %s' % rep.json()['weatherinfo']['WS'] + '\n'
		msg5 = 'humidity: %s' % rep.json()['weatherinfo']['SD'] + '\n'
		result = msg1 + msg2 + msg3 + msg4 + msg5
		self.ui.resultText.setText(result)
		
	def transCityName(self ,cityName):
		cityCode = ''
		if cityName == 'Beijing' :
			cityCode = '101010100'
		elif cityName == 'Tianjin' :
			cityCode = '101030100'
		elif cityName == 'Shanghai' :
			cityCode = '101020100'
			
		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_())  

Run the script, and the display effect is shown in the following figure.

Keywords: Python PyQt5

Added by chigley on Wed, 13 Oct 2021 02:27:29 +0300