开发一个基于 Python 的多城市天气查询工具(Tkinter + OpenWeatherMap API)



背景介绍

在日常生活中,人们常常需要了解不同城市的天气情况,例如出差、旅行或安排活动。为了提高效率,我们可以开发一个小型的桌面天气查询工具,支持用户输入多个城市名称,并实时获取这些城市的当前天气信息。该工具使用 Python 编程语言实现,结合了 Tkinter(GUI 界面)和 OpenWeatherMap API(天气数据获取),并支持用户自定义温度单位(摄氏度或华氏度)。

本项目不仅具备实用价值,还涵盖了网络请求、数据解析、GUI 设计、用户交互等核心技术点,适合中级以下开发者在 1~3 天内完成。


思路分析

功能目标

  • 用户输入多个城市名(以逗号分隔);
  • 程序调用 OpenWeatherMap API 获取每个城市的天气数据;
  • 支持用户选择温度单位(摄氏度或华氏度);
  • 使用 Tkinter 构建简单的图形界面;
  • 将结果以简洁的文本格式展示。

技术实现要点

  1. 网络请求:使用 requests 库调用 OpenWeatherMap API 获取天气数据;
  2. 数据解析:使用 json 解析 API 返回的数据;
  3. GUI 设计:使用 Tkinter 构建输入框、按钮、下拉菜单和结果显示区域;
  4. 温度单位转换:根据用户选择将温度从摄氏度转换为华氏度;
  5. 异常处理:处理网络错误、无效城市名等异常情况。

项目结构(简略)

  • main.py:主程序逻辑,包含 GUI 和主函数;
  • weather_api.py:封装 API 请求和数据解析逻辑;
  • utils.py:辅助函数,如温度转换、时间格式化等。

代码实现

以下是一个完整可运行的 Python 项目示例,使用 Tkinter 构建 GUI,调用 OpenWeatherMap API 获取天气信息。

1. 安装依赖

请确保你已安装 Python 3.8+,并安装以下依赖库:

pip install requests

2. 示例代码

# main.py
import tkinter as tk
from tkinter import ttk, messagebox
import requests
import os
from weather_api import fetch_weather_data
from utils import convert_temperature

# 设置 OpenWeatherMap API Key(请替换为你的实际 API Key)
API_KEY = "YOUR_API_KEY"

def get_weather():
    cities_input = entry_cities.get().strip()
    unit = unit_var.get()

    if not cities_input:
        messagebox.showerror("错误", "请输入城市名称")
        return

    cities = [city.strip() for city in cities_input.split(",")]
    results = []

    for city in cities:
        data = fetch_weather_data(city, API_KEY)
        if data:
            temp = data['temp']
            feels_like = data['feels_like']
            humidity = data['humidity']
            wind_speed = data['wind_speed']
            description = data['description']
            icon = data['icon']

            # 根据单位转换温度
            if unit == "华氏度":
                temp_f = convert_temperature(temp, "F")
                feels_like_f = convert_temperature(feels_like, "F")
                results.append(f"{city} - {description}, 温度:{temp_f}°F,湿度:{humidity}%,风速:{wind_speed} km/h")
            else:
                results.append(f"{city} - {description}, 温度:{temp}°C,湿度:{humidity}%,风速:{wind_speed} km/h")
        else:
            results.append(f"{city} - 无法获取天气信息")

    result_text.delete(1.0, tk.END)
    result_text.insert(tk.END, "\n".join(results))

# GUI 界面
root = tk.Tk()
root.title("多城市天气查询工具")
root.geometry("500x400")

# 城市输入框
label_cities = tk.Label(root, text="请输入城市名称(用逗号分隔):")
label_cities.pack(pady=10)

entry_cities = tk.Entry(root, width=50)
entry_cities.pack(pady=5)

# 温度单位选择
label_unit = tk.Label(root, text="选择温度单位:")
label_unit.pack(pady=10)

unit_var = tk.StringVar(value="摄氏度")
unit_dropdown = ttk.Combobox(root, textvariable=unit_var, values=["摄氏度", "华氏度"])
unit_dropdown.pack(pady=5)

# 查询按钮
btn_query = tk.Button(root, text="查询天气", command=get_weather)
btn_query.pack(pady=10)

# 显示结果区域
label_result = tk.Label(root, text="天气结果:")
label_result.pack(pady=10)

result_text = tk.Text(root, height=10, width=60)
result_text.pack()

root.mainloop()
# weather_api.py
import requests

def fetch_weather_data(city, api_key):
    """
    获取指定城市的天气数据
    :param city: 城市名称
    :param api_key: OpenWeatherMap API Key
    :return: 天气数据字典,若失败返回 None
    """
    url = f"https://api.openweathermap.org/data/2.5/weather?q={city}&appid={api_key}&units=metric"

    try:
        response = requests.get(url, timeout=10)
        response.raise_for_status()  # 如果响应状态码不是 200,抛出异常
        data = response.json()

        if data.get("cod") != 200:
            return None

        main = data.get("main", {})
        wind = data.get("wind", {})
        weather = data.get("weather", [{}])[0]

        return {
            "temp": main.get("temp"),
            "feels_like": main.get("feels_like"),
            "humidity": main.get("humidity"),
            "wind_speed": wind.get("speed"),
            "description": weather.get("description"),
            "icon": weather.get("icon")
        }

    except requests.RequestException as e:
        print(f"请求错误: {e}")
        return None
# utils.py
def convert_temperature(temp, unit):
    """
    将温度从摄氏度转换为华氏度
    :param temp: 摄氏度温度
    :param unit: 目标单位('C' 或 'F')
    :return: 转换后的温度
    """
    if unit == "F":
        return round(temp * 9/5 + 32, 1)
    return round(temp, 1)

使用说明

  1. 替换 main.py 中的 YOUR_API_KEY 为你的 OpenWeatherMap API Key;
  2. 运行 main.py,弹出 GUI 界面;
  3. 在输入框中输入城市名(如:北京, 上海, 广州);
  4. 选择温度单位(摄氏度或华氏度);
  5. 点击“查询天气”按钮,结果将显示在下方文本框中。

总结

本项目通过 Python 的 Tkinter 框架构建了一个简单但功能完整的多城市天气查询工具,结合了网络请求、数据解析、GUI 设计等核心技术点。该项目适合中级以下开发者进行练习,能够帮助理解如何将 API 数据与图形界面结合,实现用户友好的交互体验。

通过扩展,你可以进一步添加以下功能:
– 支持天气图标显示;
– 增加缓存机制;
– 添加历史记录功能;
– 实现多语言支持等。

希望这篇文章能帮助你更好地理解如何构建小型 Python 应用,并激发你对编程的兴趣!


发表回复

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