应用采用了现代化的界面设计,包括圆角边框、卡片式布局和响应式建议功能。
这个天气应用可以作为学习PyQt5开发的实例,展示了GUI设计、定时更新、数据处理和用户交互的实现方法
#!/usr/bin/env python
# -*- coding: GBK -*-
import sys
import requests
from PyQt5.QtWidgets import (QApplication, QMainWindow, QWidget, QLabel, QLineEdit, QPushButton, QVBoxLayout, QHBoxLayout,QFormLayout, QFrame, QGroupBox)
from PyQt5.QtCore import Qt, QDate, QTime, QTimer
from PyQt5.QtGui import QFont, QIcon, QPixmap, QColor, QLinearGradient, QPainterclass App(QMainWindow):def __init__(self):super().__init__()self.setWindowTitle("TianQi Pro 2025")self.setGeometry(300, 200, 650, 500)self.setStyleSheet("background-color: #f0f5ff;")# 主部件main_widget = QWidget()main_layout = QVBoxLayout()# 顶部标题栏title_frame = QFrame()title_frame.setStyleSheet("background-color: #1e88e5; color: white; border-radius: 10px;")title_layout = QHBoxLayout(title_frame)self.title_label = QLabel("天气助手")self.title_label.setFont(QFont("Microsoft YaHei", 18, QFont.Bold))title_layout.addWidget(self.title_label, 0, Qt.AlignCenter)self.date_label = QLabel()self.date_label.setFont(QFont("Arial", 10))self.update_datetime()title_layout.addWidget(self.date_label, 0, Qt.AlignRight | Qt.AlignVCenter)# 主内容区域content_group = QGroupBox("城市天气查询")content_group.setFont(QFont("Microsoft YaHei", 12))content_layout = QFormLayout()# 城市输入区域city_layout = QHBoxLayout()self.city_input = QLineEdit()self.city_input.setPlaceholderText("输入城市名称...")self.city_input.setStyleSheet("padding: 8px; border-radius: 5px;")city_layout.addWidget(self.city_input)self.search_btn = QPushButton("查询天气")self.search_btn.setStyleSheet("background-color: #42a5f5; color: white; padding: 8px; border-radius: 5px;")self.search_btn.clicked.connect(self.fetch_weather)city_layout.addWidget(self.search_btn)# 天气展示区域self.weather_frame = QFrame()self.weather_frame.setStyleSheet("""background-color: #e3f2fd;border-radius: 10px;padding: 15px;""")self.weather_layout = QVBoxLayout(self.weather_frame)# 默认内容default_label = QLabel("请输入城市名称并点击查询按钮")default_label.setAlignment(Qt.AlignCenter)self.weather_layout.addWidget(default_label)# 添加到主布局content_layout.addRow(city_layout)content_layout.addRow(self.weather_frame)content_group.setLayout(content_layout)# AI建议区域self.ai_frame = QFrame()self.ai_frame.setStyleSheet("""background-color: #bbdefb;border-radius: 10px;padding: 15px;margin-top: 20px;""")ai_layout = QVBoxLayout(self.ai_frame)self.ai_label = QLabel("助手建议:")self.ai_label.setFont(QFont("Microsoft YaHei", 10))ai_layout.addWidget(self.ai_label)self.ai_content = QLabel("根据当前天气为您提供出行和着装建议")self.ai_content.setWordWrap(True)ai_layout.addWidget(self.ai_content)# 组装主布局main_layout.addWidget(title_frame)main_layout.addWidget(content_group)main_layout.addWidget(self.ai_frame)# 配置布局main_widget.setLayout(main_layout)self.setCentralWidget(main_widget)# 创建计时器更新时间self.timer = QTimer(self)self.timer.timeout.connect(self.update_datetime)self.timer.start(60000) # 每分钟更新一次# 默认城市(可选)# self.city_input.setText("北京")# self.fetch_weather()def update_datetime(self):"""更新日期和时间显示"""current_date = QDate.currentDate().toString("yyyy年MM月dd日")current_time = QTime.currentTime().toString("hh:mm")weekday = ["周一", "周二", "周三", "周四", "周五", "周六", "周日"][QDate.currentDate().dayOfWeek()-1]self.date_label.setText(f"{current_date} {weekday} {current_time}")self.date_label.setFont(QFont("Microsoft YaHei", 10))def fetch_weather(self):"""获取天气信息(模拟数据,实际使用时连接真实API)"""city = self.city_input.text().strip()if not city:return# 实际开发时应替换为真实API调用,例如:# api_key = "YOUR_API_KEY"# url = f"https://api.weatherapi.com/v1/current.json?key={api_key}&q={city}"# 这里使用模拟数据weather_data = {"location":city,"temp_c":28,"humidity":65,"wind_kph":12,"condition":"晴","feelslike_c":30}self.display_weather(weather_data)def display_weather(self, data):"""显示天气信息"""# 清除旧内容for i in reversed(range(self.weather_layout.count())): self.weather_layout.itemAt(i).widget().setParent(None)# 创建天气显示控件# 修改display_weather方法中的城市显示location_label = QLabel(u"\U0001F4CD {} ".format(data['location']))location_label.setFont(QFont('Microsoft YaHei', 14, QFont.Bold))# 在display_weather方法中temp_label = QLabel(u"\U0001F321 温度: {}°C (体感 {}°C)".format(data['temp_c'], data['feelslike_c']))condition_label = QLabel(u"\u2601 天气: {}".format(data['condition']))humidity_label = QLabel(u"\U0001F4A7 湿度: {}%".format(data['humidity']))wind_label = QLabel(u"\U0001F343 风速: {} km/h".format(data['wind_kph']))temp_label.setFont(QFont("Arial", 12))condition_label.setFont(QFont("Arial", 12))humidity_label.setFont(QFont("Arial", 12))wind_label.setFont(QFont("Arial", 12))# 添加天气图标(实际应用中根据天气状况选择)pixmap = QPixmap("sunny.png").scaled(64, 64, Qt.KeepAspectRatio)icon_label = QLabel()icon_label.setPixmap(pixmap)icon_label.setAlignment(Qt.AlignCenter)# 添加布局self.weather_layout.addWidget(location_label)self.weather_layout.addWidget(icon_label, alignment=Qt.AlignCenter)self.weather_layout.addWidget(temp_label)self.weather_layout.addWidget(condition_label)self.weather_layout.addWidget(humidity_label)self.weather_layout.addWidget(wind_label)# 更新AI建议self.update_ai_advice(data)def update_ai_advice(self, data):"""根据天气更新AI建议"""temp = data["temp_c"]condition = data["condition"]if temp > 30:advice = "天气炎热,建议穿着清凉透气的衣物,避免长时间在户外暴晒,注意补充水分防止中暑。"color = "#d32f2f"elif temp > 20:advice = "温度适中,适宜户外活动,建议穿着轻薄衣物,享受美好的一天。"color = "#1976d2"else:advice = "天气较凉,建议添加外套,注意保暖以防感冒。"color = "#00796b"if "雨" in condition:advice += " 降水概率高,出行请携带雨具。"self.ai_content.setText(advice)self.ai_content.setStyleSheet(f"color: {color}; font-weight: bold;")self.ai_label.setText(f"TianQi AI建议 ({condition} {temp}°C):")def paintEvent(self, event):"""添加渐变背景"""painter = QPainter(self)gradient = QLinearGradient(0, 0, self.width(), self.height())gradient.setColorAt(0, QColor("#e3f2fd"))gradient.setColorAt(1, QColor("#bbdefb"))painter.fillRect(self.rect(), gradient)super().paintEvent(event)if __name__ == "__main__":# 在QApplication初始化后添加app = QApplication(sys.argv)app.setFont(QFont('Microsoft YaHei, Segoe UI Symbol, Noto Color Emoji', 10)) # 指定支持Unicode的字体window = App()window.show()sys.exit(app.exec_())