?? ? ? ?應用采用了現代化的界面設計,包括圓角邊框、卡片式布局和響應式建議功能。
????????這個天氣應用可以作為學習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_())