基于 Python 的“智能天气提醒助手”开发实战(GUI + 多线程 + 天气 API)



背景介绍

在日常生活中,天气变化直接影响我们的出行、穿衣和健康。然而,频繁手动查看天气预报既费时又容易遗漏。为了解决这个问题,我们可以开发一个“智能天气提醒助手”,它能够通过图形界面输入城市名称,自动获取天气信息,并按照用户设定的时间间隔定时提醒当前天气情况,帮助用户更好地规划生活和工作。

该项目适合中级以下 Python 开发者,涵盖了 GUI 设计、网络请求、多线程操作等关键技术点,具备良好的学习价值和实用性。通过本项目,你将学会如何构建一个交互式桌面应用,并掌握如何调用外部 API 和实现后台定时任务。


思路分析

本项目的核心功能包括以下几个部分:

  1. 图形用户界面(GUI)
    使用 tkinter 构建一个简洁的桌面应用界面,用户可以输入城市名称和设置提醒间隔。

  2. 城市经纬度获取
    使用 geopy 库将城市名称转换为经纬度,便于后续调用天气 API。

  3. 天气数据获取
    调用 OpenWeather API 获取当前天气信息,包括温度、天气状况、风速、湿度、日出日落时间等。

  4. 定时提醒功能
    使用 threading 实现后台定时任务,避免阻塞 GUI 界面,每 X 分钟弹出一次提醒窗口。

  5. 错误处理与用户提示
    对用户输入进行验证,处理 API 调用失败、城市未找到等异常情况,并通过弹窗提示用户。


代码实现

1. 安装依赖库

首先确保安装以下依赖库:

pip install tkinter geopy requests python-dotenv

注意:tkinter 是 Python 标准库的一部分,通常无需单独安装。geopyrequests 用于地理编码和网络请求,python-dotenv 用于管理 API 密钥。

2. 创建 .env 文件

在项目根目录下创建 .env 文件,用于存储 OpenWeather API 密钥:

OPENWEATHER_API_KEY=your_api_key_here

3. 完整代码(weather_reminder.py)

import os
import time
import threading
import tkinter as tk
from tkinter import messagebox
from geopy.geocoders import Nominatim
import requests
from dotenv import load_dotenv

# 加载环境变量
load_dotenv()
API_KEY = os.getenv('OPENWEATHER_API_KEY')

# 获取城市经纬度
def get_lat_long(city):
    geolocator = Nominatim(user_agent="weather_reminder")
    location = geolocator.geocode(city)
    if location:
        return location.latitude, location.longitude
    return None, None

# 获取天气信息
def get_weather(lat, long):
    url = (
        f"https://api.openweathermap.org/data/2.5/weather?lat={lat}"
        f"&lon={long}&units=metric&appid={API_KEY}"
    )
    try:
        response = requests.get(url)
        data = response.json()
        if data['cod'] != 404:
            return {
                "City": data.get("name", "N/A"),
                "Temperature": data['main']['temp'],
                "Weather": data['weather'][0]['description'].capitalize(),
                "Wind Speed": data['wind']['speed'],
                "Humidity": data['main']['humidity'],
                "Sunrise": time.strftime('%Y-%m-%d %H:%M:%S', time.gmtime(data['sys']['sunrise'] + data['timezone'])),
                "Sunset": time.strftime('%Y-%m-%d %H:%M:%S', time.gmtime(data['sys']['sunset'] + data['timezone'])),
            }
        else:
            return None
    except Exception as e:
        messagebox.showerror("错误", f"获取天气失败: {str(e)}")
        return None

# 定时提醒线程
def start_reminder(city, interval_minutes):
    lat, long = get_lat_long(city)
    if lat is None or long is None:
        messagebox.showerror("错误", "无法找到该城市的经纬度")
        return

    def reminder_loop():
        while True:
            weather = get_weather(lat, long)
            if weather:
                message = f"提醒:{weather['City']}当前天气为{weather['Weather']},气温 {weather['Temperature']}°C"
                messagebox.showinfo("天气提醒", message)
            time.sleep(interval_minutes * 60)

    thread = threading.Thread(target=reminder_loop, daemon=True)
    thread.start()
    messagebox.showinfo("提示", f"天气提醒已启动,每 {interval_minutes} 分钟提醒一次。")

# GUI 界面
def create_gui():
    root = tk.Tk()
    root.title("智能天气提醒助手")
    root.geometry("400x300")

    tk.Label(root, text="请输入城市名称:").pack(pady=5)
    city_entry = tk.Entry(root, width=30)
    city_entry.pack(pady=5)

    tk.Label(root, text="提醒间隔(分钟):").pack(pady=5)
    interval_entry = tk.Entry(root, width=10)
    interval_entry.pack(pady=5)

    def on_start():
        city = city_entry.get().strip()
        if not city:
            messagebox.showerror("错误", "请输入城市名称。")
            return
        try:
            interval = int(interval_entry.get())
            if interval <= 0:
                raise ValueError
            start_reminder(city, interval)
        except ValueError:
            messagebox.showerror("错误", "请输入有效的正整数作为提醒间隔。")

    start_button = tk.Button(root, text="开始提醒", command=on_start)
    start_button.pack(pady=20)

    root.mainloop()

if __name__ == "__main__":
    create_gui()

代码说明

  • GUI 界面:使用 tkinter 创建了一个简单的窗口,包含输入框、按钮和提示信息。
  • 地理编码:使用 geopyNominatim 服务将城市名称转换为经纬度,用于调用天气 API。
  • 天气 API 调用:通过 OpenWeather API 获取当前天气数据,返回包括温度、天气状况、风速、湿度等信息。
  • 定时提醒:使用 threading.Thread 在后台运行定时提醒任务,避免阻塞主 GUI 线程。
  • 错误处理:对用户输入和 API 调用失败进行了基本的异常处理,并通过 messagebox 提示用户。

总结

本项目是一个功能完整、结构清晰的 Python 桌面应用,适合中级以下开发者练习 GUI 编程、网络请求、多线程等核心技术。通过该项目,你不仅能掌握如何构建一个实用的天气提醒工具,还能为后续开发更复杂的桌面应用打下坚实基础。

拓展建议

  • 支持多城市提醒:添加多个城市输入框,实现多个城市的天气提醒。
  • 天气预警功能:根据天气状况(如暴雨、大风)触发特殊提醒。
  • 历史记录:将每次提醒的天气信息保存到本地文件中。
  • 图形化天气展示:使用 matplotlibseaborn 展示天气趋势图表。

通过这个项目,你可以快速上手 Python 桌面应用开发,并为未来构建更复杂的智能助手打下基础。希望你能在实践中收获乐趣与成长!


发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注