Build a Weather Query App with PyQt5 and Python: A Practical Guide
This tutorial walks through building a weather query desktop application using Python 3, PyQt5, and the requests library, covering city code data preprocessing with pandas, UI design via Qt Designer, integration with the eTouch weather API, JSON response parsing, error handling, and packaging with PyInstaller.
Development Environment
Python 3, PyQt5, and the requests library are required.
Data Preprocessing
City codes are obtained from https://www.heweather.com/documents/city.html as a CSV file. Using pandas, the CSV is read and only the 'City_ID' and 'City_CN' columns are kept. A regex function extracts the numeric part of each City_ID. A dictionary mapping Chinese city names to their numeric codes is built and saved as a JSON text file (city_code.txt) for fast lookup at runtime.
import pandas as pd
# 将下载好的文件命名为 'city_code.csv'
file = pd.read_csv('city_code.csv')
# 选取需要的两列信息
file = file.loc[:,['City_ID', 'City_CN']]
# 读取前五行信息
file.head()
# 匹配 City_ID 中的数字
def convert(x):
pat = re.compile('(\d+)')
return pat.search(x).group()
file['City_ID_map'] = file['City_ID'].map(convert)
# 建立城市与代码之间的映射关系
def city2id(file):
code_dict = {}
key = 'City_CN'
value = 'City_ID_map'
for k, v in zip(file[key], file[value]):
code_dict[k] = v
return code_dict
code_dict = city2id(file)
# 将所得的字典数据存储为 txt 文件
import json
filename = 'city_code.txt'
with open(filename, 'w') as f:
json.dump(code_dict, f)At runtime, the dictionary is loaded with:
with open(filename, 'r') as f:
text = json.load(f)UI Design
The interface is created with Qt Designer, featuring a line edit for city input, a query button, and a read-only text edit for displaying results. The generated UI file (Ui_weather.py) can be used directly.
Main Logic: Weather API Integration
The app uses the eTouch weather API: http://wthrcdn.etouch.cn/weather_mini?citykey={code}. The query_weather function sends a GET request, handles connection errors and JSON decode errors, and returns either the parsed weather information or an error message.
def query_weather(code):
# 模板网页
html = f'http://wthrcdn.etouch.cn/weather_mini?citykey={code}'
# 向网页发起请求
try:
info = requests.get(html)
info.encoding = 'utf-8'
except requests.ConnectionError:
raise
# 将获取的数据转换为 json 格式
try:
info_json = info.json()
except JSONDecodeError:
return '无法查询'
# 天气情况
data = info_json['data']
city = f"城市:{data['city']}
"
today = data['forecast'][0]
date = f"日期:{today['date']}
"
now = f"实时温度:{data['wendu']}度
"
temperature = f"温度:{today['high']} {today['low']}
"
fengxiang = f"风向:{today['fengxiang']}
"
type = f"天气:{today['type']}
"
tips = f"贴士:{data['ganmao']}
"
return city + date + now + temperature + fengxiang + type + tipsPyQt5 Widget Methods
Key widget interactions:
# 将 textEdit 设置为只读模式
self.textEdit.setReadOnly(True)
# 将鼠标焦点放在 lineEdit 编辑栏里
self.lineEdit.setFocus()
# 获取 lineEdit 中的文本
city = self.lineEdit.text()
# 设置文本
self.textEdit.setText(info)
# 清空文本
self.lineEdit.clear()Key Press Event for Enter Key
Pressing Enter triggers the query:
def keyPressEvent(self, e):
# 设置快捷键
if e.key() == Qt.Key_Return:
self.queryWeather()Packaging
Create a standalone executable with pyinstaller -w weather.py. After building, copy city_code.txt into the dist/weather folder; otherwise the program cannot find the city code mapping and will fail to run.
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
Python Crawling & Data Mining
Life's short, I code in Python. This channel shares Python web crawling, data mining, analysis, processing, visualization, automated testing, DevOps, big data, AI, cloud computing, machine learning tools, resources, news, technical articles, tutorial videos and learning materials. Join us!
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
