python 天气预报(v2.0)

上一个版本【python 自动获取天气程序(Version1.0)】实现了自动获取当前城市的天气信息,功能很简单,而且只是字符脚本。这一版本Version2.0中增强了天气预报功能,并提供了UI界面,使用起来更友好。

软件的主界面

main

 

主要菜单

menu_weather

 

 

工具栏

toolbar

软件功能

1. 启动时,自动获取用户当前城市

2.  选择任意自定义城市为当前城市,并查看该城市天气信息

city

3. 显示城市当前的天气情况:天气、温度、湿度、风力、风向、高温低温

4. 显示城市当前天气的各种天气指数:天气指数、舒适度、穿衣指数、晾晒指数等

5. 显示后续6天的天气情况:天气、气温

实现

软件分为两个模块,WeatherInfo.py和WeatherInfoUI.py,前者负责后台的天气数据获取和处理,后者负责前段UI的设计和控制。

WeatherInfo.py是V1.0版本中appGetWeather_help.py 模块的增强。

WeatherInfoUI.py基于wxPython,主要用到的控件有wx.StaticText,wx.TextCtrl,wx.StaticBitmap,wx.Dialog等,使用BoxSizer和GridBagSizer布局管理器布局。

详细实现方法,后续有时间再完整补上。

 代码

WeatherInfoUI.py模块

[python]#!/usr/bin/env python
# -*- coding: utf-8 -*-
#author:JarvisChu
#blog:zhujiangtao.com

'''天气预报信息 UI'''

import wx,time,urllib2
import WeatherInfo
from datetime import datetime #日期计算
from datetime import timedelta

class CityDialog(wx.Dialog):
'''选择城市对话框'''

def __init__(self):
wx.Dialog.__init__(self,None,-1,u'选择城市',size=(280,120))

#GridBagSizer
stTips = wx.StaticText(self,-1,u'请输入城市:')
self.tcCity = wx.TextCtrl(self,-1)

okButton = wx.Button(self, wx.ID_OK,u'确定')
okButton.SetDefault()
cancelButton = wx.Button(self, wx.ID_CANCEL, u'取消')

gbs = wx.GridBagSizer(10,10)
gbs.Add(stTips,pos=(0,0),span=wx.DefaultSpan,flag=wx.TOP|wx.BOTTOM|wx.EXPAND,border=10)
gbs.Add(self.tcCity,pos=(0,1),span=wx.DefaultSpan,flag=wx.TOP|wx.BOTTOM|wx.EXPAND,border=10)
gbs.Add(okButton,pos=(1,1),span=wx.DefaultSpan,flag=wx.TOP|wx.BOTTOM|wx.EXPAND,border=10)
gbs.Add(cancelButton,pos=(1,2),span=wx.DefaultSpan,flag=wx.TOP|wx.BOTTOM|wx.EXPAND,border=10)

self.SetSizer(gbs)

def getCity(self):
'''返回用户输入的城市'''

return self.tcCity.GetValue()

class WeatherInfoFrame(wx.Frame):
'''程序主框架'''

def __init__(self,parent=None, id=-1,title="Frame",pos=wx.DefaultPosition,size=(800,600), \
style=wx.DEFAULT_FRAME_STYLE,name='frame'):
wx.Frame.__init__(self,parent=parent,id=id,title=title,pos=pos,size=size,style=style,name=name)

#----外观设置----
self.SetBackgroundColour(wx.WHITE)

self.EmptyWeatherData() #将城市和所有天气数据,清除为N/A

#定位城市
self.current_city = self.LocateCity() #当前城市

self.UpdateWeatherInfo()#更新天气数据到系统的变量中

#----初始化界面----
self.InitUI()

def SetWindowTitle(self, cityname):
''' #设置窗体的名字'''

title = u'天气预报(v2.0) - ' + cityname.decode('gbk')
self.SetTitle(title)

def EmptyWeatherData(self):
'''将城市和所有天气数据,清除为N/A'''

self.current_temp = u'N/A'
self.current_wet =u'N/A'
self.current_wind_direction =u'N/A'
self.current_wind_strong =u'N/A'
self.current_real_time =u'N/A'
self.current_weather =u'N/A'
self.high_temp =u'N/A'
self.low_temp =u'N/A'
self.current_weather_img =u'N/A'
self.weather_index =u'N/A'
self.dress_index =u'N/A'
self.uv_index =u'N/A'
self.wash_car_index=u'N/A'
self.travel_index =u'N/A'
self.cosy_index =u'N/A'
self.excise_index =u'N/A'
self.shine_index =u'N/A'
self.sick_index =u'N/A'
self.six_day_temp = {'temp1':u'N/A','temp2':u'N/A','temp3':u'N/A','temp4':u'N/A','temp5':u'N/A','temp6':u'N/A',}
self.six_day_weather = {'weather1':u'N/A','weather2':u'N/A','weather3':u'N/A','weather4':u'N/A','weather5':u'N/A','weather6':u'N/A',}

def LocateCity(self):
'''定位当前的城市'''

try:
city_info = urllib2.urlopen( 'http://pv.sohu.com/cityjson').read()
city = city_info.split('=')[1].split(',')[2].split('"')[3] #split out the city name'''
except:
print u'自动定位城市出错'
return u'N/A'
else:
print u"您的城市:",city.decode('gbk')
#city = unicode(city,'gbk')
return city

def UpdateWeatherInfo(self):
'''更新天气数据'''

#self.current_city = unicode(self.LocateCity(),'gbk') #当前城市
#self.current_city = self.LocateCity() #当前城市
#print self.LocateCity()
if self.current_city != u'N/A':

self.SetWindowTitle(self.current_city)
#查找id
self.current_city_id = WeatherInfo.getCityCodeFromName(self.current_city)
if self.current_city_id != 'N/A':
#获取具体城市天气信息
#实时数据
dicRealTime = WeatherInfo.getCityWeather_RealTime(self.current_city_id)
self.current_temp = dicRealTime['temp'] #温度
self.current_wet = dicRealTime['sd'] #湿度
self.current_wind_direction = dicRealTime['wd'] #风向
self.current_wind_strong = dicRealTime['ws'] #风力 '2级'
self.current_real_time = dicRealTime['time'] #时间

#全天数据
dicAllDay = WeatherInfo.getCityWeather_AllDay(self.current_city_id)
self.current_weather = dicAllDay['weather'] #天气,'晴转多云'
self.high_temp = dicAllDay['high'] #最高温
self.low_temp = dicAllDay['low'] #最低温
self.current_weather_img = dicAllDay['img']

#详细的天气信息和最近6天的天气
dicDetail = WeatherInfo.getCityWeatherDetail_SixDay(self.current_city_id)
self.weather_index = dicDetail['index'] #天气指数 #冷
self.dress_index = dicDetail['cy'] #穿衣指数 #建议....
self.uv_index = dicDetail['zw'] #紫外线指数 #最弱
self.wash_car_index= dicDetail['xc'] #洗车指数 #不宜
self.travel_index = dicDetail['tr'] #旅游指数 #很适宜
self.cosy_index = dicDetail['co'] #舒适度 #较舒适
self.excise_index = dicDetail['cl'] #晨练指数 #较适宜
self.shine_index = dicDetail['ls'] #晾晒指数 #不太适宜
self.sick_index = dicDetail['ag'] #过敏指数 #不易发"

self.six_day_temp = {}
self.six_day_weather = {}
for i in range(1,7):
temp = 'temp'+str(i)
weather = 'weather'+str(i)
self.six_day_temp[temp] = dicDetail[temp]
self.six_day_weather[weather] = dicDetail[weather]
return True
else:
return False
else:
return False

def InitMenu(self):
'''初始化菜单栏'''

#菜单ID
self.IDM_EXIT = wx.NewId()
self.IDM_ABOUT = wx.NewId()
self.IDM_UPDATE = wx.NewId()
self.IDM_TREND = wx.NewId()
self.IDM_CITY = wx.NewId()

#菜单图标
self.imgExit = wx.Bitmap('img/exit.png')
self.imgAbout = wx.Bitmap('img/about.png')
self.imgUpdate = wx.Bitmap('img/update.png')
self.imgTrend = wx.Bitmap('img/trend.png')
self.imgCity = wx.Bitmap('img/city.png')

#菜单栏
self.menuBar = wx.MenuBar()

#菜单: 文件
menuFile = wx.Menu()
miExit = wx.MenuItem(menuFile,self.IDM_EXIT,u'退出(&E)',u'退出软件')#图标菜单项
miExit.SetBitmap(self.imgExit)
menuFile.AppendItem(miExit)
self.menuBar.Append(menuFile,u'文件(&F)')

#菜单:天气
menuWeather = wx.Menu()
miUpdate = wx.MenuItem(menuWeather,self.IDM_UPDATE,u'更新(&U)',u'更新天气信息')
miTrend = wx.MenuItem(menuWeather,self.IDM_TREND,u'趋势(&Q)',u'天气趋势图表')
miCity = wx.MenuItem(menuWeather,self.IDM_CITY,u'城市(&C)',u'选择城市')
miUpdate.SetBitmap(self.imgUpdate)
miTrend.SetBitmap(self.imgTrend)
miCity.SetBitmap(self.imgCity)
menuWeather.AppendItem(miUpdate)
menuWeather.AppendItem(miTrend)
menuWeather.AppendItem(miCity)
self.menuBar.Append(menuWeather,u'天气(&W)')

#菜单:关于
menuAbout = wx.Menu() #
miAbout = wx.MenuItem(menuAbout,self.IDM_ABOUT,u'关于',u'天气预报(v2.0) - JarvisChu - zhujiangtao.com')
miAbout.SetBitmap(self.imgAbout)
menuAbout.AppendItem(miAbout)
self.menuBar.Append(menuAbout,u'关于(&A)')

#菜单栏附加到窗口
self.SetMenuBar(self.menuBar)

#----菜单事件响应----
self.Bind(wx.EVT_MENU,self.OnExit,id=self.IDM_EXIT)
self.Bind(wx.EVT_MENU,self.OnAbout,id=self.IDM_ABOUT)
self.Bind(wx.EVT_MENU,self.OnUpdate,id=self.IDM_UPDATE)
self.Bind(wx.EVT_MENU,self.OnTrend,id=self.IDM_TREND)
self.Bind(wx.EVT_MENU,self.OnCity,id=self.IDM_CITY)
pass

def InitToolBar(self):
'''初始化快捷工具栏'''

self.toolBar = self.CreateToolBar()
self.toolBar.AddSimpleTool(self.IDM_UPDATE,self.imgUpdate,u'更新(&U)',u'更新天气信息')
self.toolBar.AddSimpleTool(self.IDM_TREND,self.imgTrend,u'趋势(&Q)',u'天气趋势图表')
self.toolBar.AddSimpleTool(self.IDM_CITY, self.imgCity,u'城市',u'选择城市')
self.toolBar.AddSimpleTool(self.IDM_ABOUT, self.imgAbout,u'关于',u'天气预报(v2.0) - JarvisChu - zhujiangtao.com')
self.toolBar.AddSimpleTool(self.IDM_EXIT,self.imgExit,u'退出',u'退出软件')
self.toolBar.Realize()

def InitMainWindowControls(self):
'''初始化主界面窗口的控件'''

self.mainPanel = wx.Panel(self,-1)

#-------------------------------------------------------------------
#上

self.imgLocatedCity = wx.Bitmap('img/location.png')
#当前城市
sbCity = wx.StaticBitmap(self.mainPanel,bitmap=self.imgLocatedCity)
#self.current_city = u'杭州'
self.stCurCity = wx.StaticText(self.mainPanel,-1,self.current_city)
font18 = wx.Font(18, wx.DECORATIVE, wx.FONTWEIGHT_NORMAL, wx.NORMAL)
self.stCurCity.SetFont(font18)

#更新时间,初始化为当前时间
stUpdateTime = wx.StaticText(self.mainPanel,-1,u'更新时间: ')
stUpdateTime.SetFont(wx.Font(14, wx.DECORATIVE, wx.FONTWEIGHT_NORMAL, wx.NORMAL))

update_time = time.strftime('%Y-%m-%d %H:%M:%S',time.localtime(time.time()))
self.tcUpdateTime = wx.TextCtrl(self.mainPanel,-1,update_time,style=wx.TE_LEFT|wx.TE_READONLY|wx.TE_RICH2)
self.tcUpdateTime.SetBackgroundColour(wx.Colour(250,250,250))
self.tcUpdateTime.SetFont(wx.Font(12, wx.DECORATIVE, wx.FONTWEIGHT_NORMAL, wx.NORMAL))

#更新按钮事件响应
self.IDC_BTN_UPDATE = wx.NewId()
btnUpdate =wx.BitmapButton(self.mainPanel,id=self.IDC_BTN_UPDATE,bitmap=self.imgUpdate,style=wx.BU_EXACTFIT)
btnUpdate.Bind(wx.EVT_BUTTON,self.OnClickBtnUpdate)

#BoxSizer布局 - 上
bsHead = wx.BoxSizer(wx.HORIZONTAL)
bsHead.Add(sbCity,0,flag=wx.ALL|wx.ALIGN_CENTER|wx.EXPAND,border=10)
bsHead.Add(self.stCurCity,2,flag=wx.ALL|wx.ALIGN_CENTER,border=10)
bsHead.Add(stUpdateTime,0,flag=wx.TOP|wx.BOTTOM|wx.LEFT|wx.ALIGN_RIGHT|wx.ALIGN_CENTER_VERTICAL,border=10)
bsHead.Add(self.tcUpdateTime,2,flag=wx.TOP|wx.BOTTOM|wx.ALIGN_LEFT|wx.ALIGN_CENTER_VERTICAL,border=10)
bsHead.Add(btnUpdate,0,flag=wx.ALL|wx.ALIGN_RIGHT|wx.ALIGN_CENTER_VERTICAL,border=10)

#-------------------------------------------------------------------
#中

#当前温度
self.imgTemp = wx.Bitmap('img/temperature.png')
sbCurTemp = wx.StaticBitmap(self.mainPanel,bitmap=self.imgTemp)
self.stCurTemp = wx.StaticText(self.mainPanel,-1,u'当前温度: '+str(self.current_temp)+u" ℃")
self.stCurTemp.SetFont(wx.Font(14, wx.DECORATIVE, wx.FONTWEIGHT_NORMAL, wx.NORMAL))
#当前湿度
self.imgWet = wx.Bitmap('img/wet.png')
sbCurWet = wx.StaticBitmap(self.mainPanel,bitmap=self.imgWet)
self.stCurWet = wx.StaticText(self.mainPanel,-1,u'当前湿度: '+str(self.current_wet))
self.stCurWet.SetFont(wx.Font(14, wx.DECORATIVE, wx.FONTWEIGHT_NORMAL, wx.NORMAL))
#当前风向
self.imgWindDirection = wx.Bitmap('img/wind_direction.png')
sbCurWindDirection = wx.StaticBitmap(self.mainPanel,bitmap=self.imgWindDirection)
self.stCurWindDirection = wx.StaticText(self.mainPanel,-1,u'当前风向:'+self.current_wind_direction)
self.stCurWindDirection.SetFont(wx.Font(14, wx.DECORATIVE, wx.FONTWEIGHT_NORMAL, wx.NORMAL))
#当前风力
self.imgWindStrong = wx.Bitmap('img/wind_strong.png')
sbCurWindStrong = wx.StaticBitmap(self.mainPanel,bitmap=self.imgWindStrong)
self.stCurWindStrong = wx.StaticText(self.mainPanel,-1,u'当前风力: '+self.current_wind_strong)
self.stCurWindStrong.SetFont(wx.Font(14, wx.DECORATIVE, wx.FONTWEIGHT_NORMAL, wx.NORMAL))
#当前天气
self.imgWeather = wx.Bitmap('img/weather.png')
sbWeatherInfo = wx.StaticBitmap(self.mainPanel,bitmap=self.imgWeather)
self.stCurWeather = wx.StaticText(self.mainPanel,-1,u'天气情况:'+self.current_weather)
self.stCurWeather.SetFont(wx.Font(14, wx.DECORATIVE, wx.FONTWEIGHT_NORMAL, wx.NORMAL))
#最低最高温
self.imgTempRange = wx.Bitmap('img/temprange.png')
sbTempRange = wx.StaticBitmap(self.mainPanel,bitmap=self.imgTempRange)
self.stCurTempRange = wx.StaticText(self.mainPanel,-1,u'温度范围:'+self.low_temp+u'~'+self.high_temp)
self.stCurTempRange.SetFont(wx.Font(14, wx.DECORATIVE, wx.FONTWEIGHT_NORMAL, wx.NORMAL))

#GridBagSizer布局
gbsMid = wx.GridBagSizer(10,10)
gbsMid.Add(sbCurTemp,pos=(0,0),span=wx.DefaultSpan,flag=wx.EXPAND)
gbsMid.Add(self.stCurTemp,pos=(0,1),span=wx.DefaultSpan,flag=wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_LEFT,border=5)
gbsMid.Add(sbCurWet,pos=(0,2),span=wx.DefaultSpan,flag=wx.LEFT|wx.EXPAND,border=10)
gbsMid.Add(self.stCurWet,pos=(0,3),span=wx.DefaultSpan,flag=wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_LEFT,border=5)

gbsMid.Add(sbCurWindDirection,pos=(1,0),span=wx.DefaultSpan,flag=wx.EXPAND)
gbsMid.Add(self.stCurWindDirection,pos=(1,1),span=wx.DefaultSpan,flag=wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_LEFT,border=5)
gbsMid.Add(sbCurWindStrong,pos=(1,2),span=wx.DefaultSpan,flag=wx.LEFT|wx.EXPAND,border=10)
gbsMid.Add(self.stCurWindStrong,pos=(1,3),span=wx.DefaultSpan,flag=wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_LEFT,border=5)

gbsMid.Add(sbWeatherInfo,pos=(2,0),span=wx.DefaultSpan,flag=wx.BOTTOM|wx.EXPAND,border=10)
gbsMid.Add(self.stCurWeather,pos=(2,1),span=wx.DefaultSpan,flag=wx.BOTTOM|wx.RIGHT|wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_LEFT,border=10)
gbsMid.Add(sbTempRange,pos=(2,2),span=wx.DefaultSpan,flag=wx.BOTTOM|wx.LEFT|wx.EXPAND,border=10)
gbsMid.Add(self.stCurTempRange,pos=(2,3),span=wx.DefaultSpan,flag=wx.BOTTOM|wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_LEFT,border=10)

gbsMid.AddGrowableCol(1,1)
gbsMid.AddGrowableCol(3,1)
gbsMid.AddGrowableRow(0,1)
gbsMid.AddGrowableRow(1,1)
gbsMid.AddGrowableRow(2,1)

#GridBagSizer - 天气指数
#天气指数 #冷
#穿衣指数 #建议....
#紫外线指数 #最弱
#洗车指数 #不宜
#旅游指数 #很适宜
#舒适度 #较舒适
#晨练指数 #较适宜
#晾晒指数 #不太适宜
#过敏指数 #不易发"

gbsWeatherIndex = wx.GridBagSizer(5,5)
labelWeatherIndex = wx.StaticText(self.mainPanel,-1,u'天气指数:')
self.stWeatherIndex = wx.StaticText(self.mainPanel,-1,self.weather_index)
labelWeatherIndex.SetFont(wx.Font(12, wx.DECORATIVE, wx.FONTWEIGHT_NORMAL, wx.NORMAL))
self.stWeatherIndex.SetFont(wx.Font(10, wx.DECORATIVE, wx.FONTWEIGHT_NORMAL, wx.NORMAL))

labelDressIndex = wx.StaticText(self.mainPanel,-1,u'穿衣指数:')
#self.stDressIndex = wx.StaticText(self.mainPanel,-1,self.dress_index)
self.stDressIndex = wx.TextCtrl(self.mainPanel,-1,self.dress_index,style=wx.TE_RIGHT|wx.TE_READONLY|wx.TE_RICH2)
labelDressIndex.SetFont(wx.Font(12, wx.DECORATIVE, wx.FONTWEIGHT_NORMAL, wx.NORMAL))
self.stDressIndex.SetFont(wx.Font(10, wx.DECORATIVE, wx.FONTWEIGHT_NORMAL, wx.NORMAL))

labelCosyIndex = wx.StaticText(self.mainPanel,-1,u'舒适度:')
self.stCosyIndex = wx.StaticText(self.mainPanel,-1,self.cosy_index)
labelCosyIndex.SetFont(wx.Font(12, wx.DECORATIVE, wx.FONTWEIGHT_NORMAL, wx.NORMAL))
self.stCosyIndex.SetFont(wx.Font(10, wx.DECORATIVE, wx.FONTWEIGHT_NORMAL, wx.NORMAL))

labelExciseIndex = wx.StaticText(self.mainPanel,-1,u'晨练指数:')
self.stExciseIndex = wx.StaticText(self.mainPanel,-1,self.excise_index)
labelExciseIndex.SetFont(wx.Font(12, wx.DECORATIVE, wx.FONTWEIGHT_NORMAL, wx.NORMAL))
self.stExciseIndex.SetFont(wx.Font(10, wx.DECORATIVE, wx.FONTWEIGHT_NORMAL, wx.NORMAL))

labelUVIndex = wx.StaticText(self.mainPanel,-1,u'紫外线指数:')
self.stUVIndex = wx.StaticText(self.mainPanel,-1,self.uv_index)
labelUVIndex.SetFont(wx.Font(12, wx.DECORATIVE, wx.FONTWEIGHT_NORMAL, wx.NORMAL))
self.stUVIndex.SetFont(wx.Font(10, wx.DECORATIVE, wx.FONTWEIGHT_NORMAL, wx.NORMAL))

labelShineIndex = wx.StaticText(self.mainPanel,-1,u'晾晒指数:')
self.stShineIndex = wx.StaticText(self.mainPanel,-1,self.shine_index)
labelShineIndex.SetFont(wx.Font(12, wx.DECORATIVE, wx.FONTWEIGHT_NORMAL, wx.NORMAL))
self.stShineIndex.SetFont(wx.Font(10, wx.DECORATIVE, wx.FONTWEIGHT_NORMAL, wx.NORMAL))

labelWashCarIndex = wx.StaticText(self.mainPanel,-1,u'洗车指数:')
self.stWashCarIndex = wx.StaticText(self.mainPanel,-1,self.wash_car_index)
labelWashCarIndex.SetFont(wx.Font(12, wx.DECORATIVE, wx.FONTWEIGHT_NORMAL, wx.NORMAL))
self.stWashCarIndex.SetFont(wx.Font(10, wx.DECORATIVE, wx.FONTWEIGHT_NORMAL, wx.NORMAL))

labelTravelIndex = wx.StaticText(self.mainPanel,-1,u'旅游指数:')
self.stTravelIndex = wx.StaticText(self.mainPanel,-1,self.travel_index)
labelTravelIndex.SetFont(wx.Font(12, wx.DECORATIVE, wx.FONTWEIGHT_NORMAL, wx.NORMAL))
self.stTravelIndex.SetFont(wx.Font(10, wx.DECORATIVE, wx.FONTWEIGHT_NORMAL, wx.NORMAL))

labelSickIndex = wx.StaticText(self.mainPanel,-1,u'过敏指数:')
self.stSickIndex = wx.StaticText(self.mainPanel,-1,self.sick_index)
labelSickIndex.SetFont(wx.Font(12, wx.DECORATIVE, wx.FONTWEIGHT_NORMAL, wx.NORMAL))
self.stSickIndex.SetFont(wx.Font(10, wx.DECORATIVE, wx.FONTWEIGHT_NORMAL, wx.NORMAL))

flag_tmp = wx.TOP|wx.BOTTOM|wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_LEFT
gbsWeatherIndex.Add(labelWeatherIndex,pos=(0,0),span=wx.DefaultSpan,flag=flag_tmp,border=5)#天气指数 #row 0
gbsWeatherIndex.Add(self.stWeatherIndex,pos=(0,1),span=(1,2),flag=flag_tmp,border=5)
gbsWeatherIndex.Add(labelCosyIndex,pos=(0,3),span=wx.DefaultSpan,flag=flag_tmp,border=5) #舒适度
gbsWeatherIndex.Add(self.stCosyIndex,pos=(0,4),span=(1,2),flag=flag_tmp,border=5)
gbsWeatherIndex.Add(labelDressIndex,pos=(1,0),span=wx.DefaultSpan,flag=flag_tmp,border=5) #穿衣 #row 1
gbsWeatherIndex.Add(self.stDressIndex,pos=(1,1),span=(1,5),flag=wx.TOP|wx.BOTTOM|wx.EXPAND,border=5)

gbsWeatherIndex.Add(labelExciseIndex,pos=(2,0),span=wx.DefaultSpan,flag=flag_tmp,border=5) #晨练#row 2
gbsWeatherIndex.Add(self.stExciseIndex,pos=(2,1),span=(1,2),flag=flag_tmp,border=5)
gbsWeatherIndex.Add(labelShineIndex,pos=(2,3),span=wx.DefaultSpan,flag=flag_tmp,border=5) #晾晒
gbsWeatherIndex.Add(self.stShineIndex,pos=(2,4),span=(1,2),flag=flag_tmp,border=5)
gbsWeatherIndex.Add(labelWashCarIndex,pos=(3,0),span=wx.DefaultSpan,flag=flag_tmp,border=5) #洗车 #row 3
gbsWeatherIndex.Add(self.stWashCarIndex,pos=(3,1),span=(1,2),flag=flag_tmp,border=5)
gbsWeatherIndex.Add(labelTravelIndex,pos=(3,3),span=wx.DefaultSpan,flag=flag_tmp,border=5) #旅游
gbsWeatherIndex.Add(self.stTravelIndex,pos=(3,4),span=(1,2),flag=flag_tmp,border=5)
gbsWeatherIndex.Add(labelUVIndex,pos=(4,0),span=wx.DefaultSpan,flag=flag_tmp,border=5) #紫外线 #row 4
gbsWeatherIndex.Add(self.stUVIndex,pos=(4,1),span=(1,2),flag=flag_tmp,border=5)
gbsWeatherIndex.Add(labelSickIndex,pos=(4,3),span=wx.DefaultSpan,flag=flag_tmp,border=5)#过敏
gbsWeatherIndex.Add(self.stSickIndex,pos=(4,4),span=(1,2),flag=flag_tmp,border=5)

#gbsWeatherIndex.AddGrowableCol(0,1)
gbsWeatherIndex.AddGrowableCol(1,1)
gbsWeatherIndex.AddGrowableCol(3,1)

gbsWeatherIndex.AddGrowableRow(0,1)
gbsWeatherIndex.AddGrowableRow(1,1)
gbsWeatherIndex.AddGrowableRow(2,1)
gbsWeatherIndex.AddGrowableRow(3,1)
gbsWeatherIndex.AddGrowableRow(4,1)

#BoxSizer - 中
vline = wx.StaticLine(self.mainPanel,style=wx.LI_VERTICAL)

bsMid = wx.BoxSizer(wx.HORIZONTAL)
bsMid.Add(gbsMid,1,flag=wx.ALL|wx.EXPAND,border=10)
bsMid.Add(vline,0,flag=wx.LEFT|wx.RIGHT|wx.EXPAND,border=10)
bsMid.Add(gbsWeatherIndex,1,flag=wx.ALL|wx.EXPAND,border=10)

#-------------------------------------------------------------------
#下

#GridBagSizer布局 - 下
gbsFooter = wx.GridBagSizer()

self.tcDaySix = []
self.tcWeatherSix=[]
self.tcTempSix=[]
today = datetime.now()
for i in range(1,7):
dif = timedelta(days=i)
day = today+dif
sDay = day.strftime('%Y-%m-%d')
weather = 'weather'+str(i)
temp = 'temp'+str(i)
self.tcDaySix.append(wx.StaticText(self.mainPanel,-1,sDay))
self.tcWeatherSix.append(wx.StaticText(self.mainPanel,-1,self.six_day_weather[weather]))
self.tcTempSix.append(wx.StaticText(self.mainPanel,-1,self.six_day_temp[temp]))

gbsFooter.Add(self.tcDaySix[i-1],pos=(0,i-1),span=(1,1),flag=wx.ALL|wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_CENTER,border=10)
gbsFooter.Add(self.tcWeatherSix[i-1],pos=(1,i-1),span=(1,1),flag=wx.ALL|wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_CENTER,border=10)
gbsFooter.Add(self.tcTempSix[i-1],pos=(2,i-1),span=(1,1),flag=wx.ALL|wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_CENTER,border=10)
gbsFooter.AddGrowableCol(0,1)
gbsFooter.AddGrowableCol(1,1)
gbsFooter.AddGrowableCol(2,1)
gbsFooter.AddGrowableCol(3,1)
gbsFooter.AddGrowableCol(4,1)
gbsFooter.AddGrowableCol(5,1)
#---------------------------------------------------------------------
#BoxSizer布局 - 整体框架

line1 = wx.StaticLine(self.mainPanel)
line2 = wx.StaticLine(self.mainPanel)

bsAll = wx.BoxSizer(wx.VERTICAL)
bsAll.Add(bsHead,0,flag=wx.TOP|wx.BOTTOM|wx.EXPAND,border=5)
bsAll.Add(line1,0,flag=wx.TOP|wx.BOTTOM|wx.EXPAND,border=10)
bsAll.Add(bsMid,1,flag=wx.TOP|wx.BOTTOM|wx.EXPAND,border=10)
bsAll.Add(line2,0,flag=wx.TOP|wx.BOTTOM|wx.EXPAND,border=10)
bsAll.Add(gbsFooter,0,flag=wx.TOP|wx.BOTTOM|wx.EXPAND,border=10)
self.mainPanel.SetSizer(bsAll)

def InitUI(self):
'''初始化UI界面,包括菜单、工具栏、窗口控件'''

self.mainIcon = wx.Icon('img/main.ico',wx.BITMAP_TYPE_ICO)
self.SetIcon(self.mainIcon) #设置窗口图标

self.InitMenu()#初始化菜单栏
self.InitToolBar() #初始化快捷工具栏
self.statusBar = self.CreateStatusBar()#状态栏

self.InitMainWindowControls()#初始化主界面窗口的控件

def OnExit(self,event):
'''退出程序'''

self.Close(True)

def OnAbout(self,event):
'''关于对话框'''

about = wx.MessageDialog(None, u'天气预报(v2.0)\n作者:JarvisChu\n博客:zhujiangtao.com',u'关于', wx.OK)
about.ShowModal()
about.Destroy()

def OnTrend(self,event):
'''趋势,菜单的点击响应'''

print 'OnTrend'

def OnCity(self,event):
'''选择城市'''

print 'OnCity'

#cityFrame = wx.Frame(self,-1,title=u'输入城市')
#cityFrame.Show()
#cityFrame.Destroy()

cityDlg = CityDialog()
if cityDlg.ShowModal() == wx.ID_OK:
print 'ok'
rst = cityDlg.getCity()
print rst
city = WeatherInfo.getCityCodeFromName(rst.encode('gbk'))
if city != u'N/A':
print 'find'
print city
self.current_city = rst.encode('gbk')
self.UpdateWeatherUI()
cityDlg.Destroy()

def OnUpdate(self,event):
'''更新天气,菜单的点击响应'''

print 'Click Update menu'
self.UpdateWeatherUI()

def OnClickBtnUpdate(self,event):
'''更新天气,Button按钮的点击响应'''

print 'Click Button'
self.UpdateWeatherUI()

def UpdateWeatherUI(self):
'''更新窗口上各控件的天气'''

self.UpdateWeatherInfo()

#城市
self.stCurCity.SetLabel(self.current_city)

#更新时间
update_time = time.strftime('%Y-%m-%d %H:%M:%S',time.localtime(time.time()))
self.tcUpdateTime.SetLabel(update_time)

self.stCurTemp.SetLabel(u'当前温度: '+self.current_temp+u" ℃")
self.stCurWet.SetLabel(u'当前湿度: '+self.current_wet)
self.stCurWindDirection.SetLabel(u'当前风向: '+self.current_wind_direction)
self.stCurWindStrong.SetLabel(u'当前风力: '+self.current_wind_strong)
self.stCurWeather.SetLabel(u'天气情况:'+self.current_weather)
self.stCurTempRange.SetLabel(u'温度范围:'+self.low_temp+u'~'+self.high_temp)
#
self.stWeatherIndex.SetLabel(self.weather_index)
self.stCosyIndex.SetLabel(self.cosy_index)
self.stDressIndex.SetLabel(self.dress_index)
self.stExciseIndex.SetLabel(self.excise_index)
self.stShineIndex.SetLabel(self.shine_index)
self.stWashCarIndex.SetLabel(self.wash_car_index)
self.stTravelIndex.SetLabel(self.travel_index)
self.stSickIndex.SetLabel(self.sick_index)

#
today = datetime.now()
for i in range(1,7):
dif = timedelta(days=i)
day = today+dif
sDay = day.strftime('%Y-%m-%d')
weather = 'weather'+str(i)
temp = 'temp'+str(i)
(self.tcDaySix[i-1]).SetLabel(sDay)
(self.tcWeatherSix[i-1]).SetLabel(self.six_day_weather[weather])
(self.tcTempSix[i-1]).SetLabel(self.six_day_temp[temp])

class WeatherInfoApp(wx.App):
'''主程序类'''

def OnInit(self):
mainFrmId = wx.NewId()
self.frame = WeatherInfoFrame(parent=None, id=mainFrmId, title=u'天气预报(v2.0)')
self.frame.Show()
self.SetTopWindow(self.frame)
return True

if __name__ == "__main__":
app = WeatherInfoApp()
app.MainLoop()
[/python]

 

WeatherInfo.py模块

[python]#! /usr/bin/env python
#coding=utf-8
#Author: JarvisChu
#Blog: zhujiangtao.com,blog.csdn.net/jarvischu

import sys,urllib2,json

cityList_main = [ #全国主要城市
#华北
{'code':"101010100", 'name':"北京"},
{'code':"101030100", 'name':"天津"},
{'code':"101090101", 'name':"石家庄"},
{'code':"101100101", 'name':"太原"},
{'code':"101080101", 'name':"呼和浩特"},
{'code':"101090201", 'name':"保定"},
{'code':"101100201", 'name':"大同"},
{'code':"101080201", 'name':"包头"},
{'code':"101090402", 'name':"承德"},
{'code':"101100401", 'name':"晋中"},
{'code':"101080501", 'name':"通辽"},
{'code':"101091101", 'name':"秦皇岛"},
#东北
{'code':"101050101", 'name':"哈尔滨"},
{'code':"101060101", 'name':"长春"},
{'code':"101070101", 'name':"沈阳"},
{'code':"101050201", 'name':"齐齐哈尔"},
{'code':"101060201", 'name':"吉林"},
{'code':"101070201", 'name':"大连"},
{'code':"101050301", 'name':"牡丹江"},
{'code':"101060301", 'name':"延吉"},
{'code':"101070301", 'name':"鞍山"},
{'code':"101050501", 'name':"绥化"},
{'code':"101060601", 'name':"白城"},
{'code':"101071401", 'name':"葫芦岛"},
#华南
{'code':"101280101", 'name':"广州"},
{'code':"101300101", 'name':"南宁"},
{'code':"101310101", 'name':"海口"},
{'code':"101320101", 'name':"香港"},
{'code':"101330101", 'name':"澳门"},
{'code':"101280601", 'name':"深圳"},
{'code':"101300501", 'name':"桂林"},
{'code':"101310201", 'name':"三亚"},
{'code':"101280701", 'name':"珠海"},
{'code':"101281701", 'name':"中山"},
{'code':"101301001", 'name':"百色"},
{'code':"101310215", 'name':"万宁"},
#西北
{'code':"101110101", 'name':"西安"},
{'code':"101160101", 'name':"兰州"},
{'code':"101150101", 'name':"西宁"},
{'code':"101170101", 'name':"银川"},
{'code':"101130101", 'name':"乌鲁木齐"},
{'code':"101110300", 'name':"延安"},
{'code':"101110901", 'name':"宝鸡"},
{'code':"101160901", 'name':"天水"},
{'code':"101170301", 'name':"吴忠"},
{'code':"101130501", 'name':"吐鲁番"},
{'code':"101160801", 'name':"酒泉"},
{'code':"101170401", 'name':"固原"},
#西南
{'code':"101040100", 'name':"重庆"},
{'code':"101270101", 'name':"成都"},
{'code':"101260101", 'name':"贵阳"},
{'code':"101290101", 'name':"昆明"},
{'code':"101140101", 'name':"拉萨"},
{'code':"101270401", 'name':"绵阳"},
{'code':"101260201", 'name':"遵义"},
{'code':"101290201", 'name':"大理"},
{'code':"101271401", 'name':"乐山"},
{'code':"101260801", 'name':"六盘水"},
{'code':"101291401", 'name':"丽江"},
#华东
{'code':"101020100", 'name':"上海"},
{'code':"101230101", 'name':"福州"},
{'code':"101220101", 'name':"合肥"},
{'code':"101240101", 'name':"南昌"},
{'code':"101120101", 'name':"济南"},
{'code':"101210301", 'name':"嘉兴"},
{'code':"101190101", 'name':"南京"},
{'code':"101210401", 'name':"宁波"},
{'code':"101210101", 'name':"杭州"},
{'code':"101190401", 'name':"苏州"},
{'code':"101120201", 'name':"青岛"},
{'code':"101230201", 'name':"厦门"},
{'code':"101340101", 'name':"台北"},
#华中
{'code':"101180101", 'name':"郑州"},
{'code':"101200101", 'name':"武汉"},
{'code':"101250101", 'name':"长沙"},
{'code':"101180201", 'name':"安阳"},
{'code':"101200201", 'name':"襄阳"},
{'code':"101250201", 'name':"湘潭"},
{'code':"101250301", 'name':"株洲"},
{'code':"101180401", 'name':"许昌"},
{'code':"101250601", 'name':"常德"},
{'code':"101251101", 'name':"张家界"},
{'code':"101200401", 'name':"孝感"},
{'code':"101201401", 'name':"荆门"}
]

def convertName(cityName):
'''#将 “浙江省杭州市” 转换成“杭州”'''

name = unicode(cityName, "gbk")

if name.find(u"省") !=-1:# 包含'省'
#print u'有省'
name=name.split(u'省')[1]
if name.find(u"市") != -1:#包含‘市’
#print u'有市'
name=name.split(u'市')[0]
return name

def getCityCodeFromName(cityName):
'''从城市名获取城市ID'''

cityName = convertName(cityName)
for item in cityList_main:
#n = unicode(item['name'],'utf-8')
#print n,cityName
if unicode(item['name'],'utf-8')==cityName:
#print 'equal'
return item['code']
return 'N/A'

def getCityWeather_RealTime(cityID):
'''获取实时天气,返回温度、湿度、风向、风力、时间的字典类型数据'''

url = "http://www.weather.com.cn/data/sk/" + str(cityID) + ".html"
try:
req=urllib2.Request(url)
stdout = urllib2.urlopen(url)
weatherInfomation = stdout.read().decode('utf-8')
print 'realtime- ',weatherInfomation
#{"weatherinfo":{"city":"杭州","cityid":"101210101","temp":"8","WD":"东南风","WS":"1级","SD":"45%","WSE":"1","time":"15:45","isRadar":"1","Radar":"JC_RADAR_AZ9571_JB"}}

jsonDatas = json.loads(weatherInfomation)

city = jsonDatas["weatherinfo"]["city"] #城市
cityid = jsonDatas["weatherinfo"]["cityid"] #城市id
temp = jsonDatas["weatherinfo"]["temp"] #温度
wd = jsonDatas["weatherinfo"]["WD"] #风向
ws = jsonDatas["weatherinfo"]["WS"] #风力
sd = jsonDatas["weatherinfo"]["SD"] #相对湿度
wse = jsonDatas["weatherinfo"]["WSE"] #风力,不含“级”字
tm = jsonDatas["weatherinfo"]["time"] #时间
isRadar = jsonDatas["weatherinfo"]["isRadar"] #是否有雷达图
Radar = jsonDatas["weatherinfo"]["isRadar"] #有雷达图
except:
print 'getCityWeather_RealTime Error!'
return {}
else:
return {'temp':temp,'sd':sd,'wd':wd,'ws':ws,'time':tm}

#返回dict类型:
def getCityWeatherDetail_SixDay(cityID):
url = "http://m.weather.com.cn/data/" + str(cityID) + ".html"
try:
print 'aaaa'
req=urllib2.Request(url)
stdout = urllib2.urlopen(url)
weatherInfomation = stdout.read().decode('utf-8')

print 'detail - ',weatherInfomation
'''
{"weatherinfo":{"city":"杭州","city_en":"hangzhou","date_y":"2014年1月10日","date":"","week":"星期五","fchh":"18","cityid":"101210101",\
"temp1":"3℃~7℃","temp2":"5℃~6℃","temp3":"2℃~6℃","temp4":"1℃~6℃","temp5":"-1℃~7℃","temp6":"-2℃~7℃",\
"tempF1":"37.4℉~44.6℉","tempF2":"41℉~42.8℉","tempF3":"35.6℉~42.8℉","tempF4":"33.8℉~42.8℉","tempF5":"30.2℉~44.6℉","tempF6":"28.4℉~44.6℉",\
"weather1":"小雨","weather2":"小雨","weather3":"小雨转雨夹雪","weather4":"雨夹雪转阴","weather5":"多云转晴","weather6":"晴转多云",\
"img1":"7","img2":"99","img3":"7","img4":"99","img5":"7","img6":"6","img7":"6","img8":"2","img9":"1","img10":"0","img11":"0","img12":"1",\
"img_single":"7","img_title1":"小雨","img_title2":"小雨","img_title3":"小雨","img_title4":"小雨","img_title5":"小雨","img_title6":"雨夹雪","img_title7":"雨夹雪","img_title8":"阴","img_title9":"多云","img_title10":"晴","img_title11":"晴","img_title12":"多云",\
"img_title_single":"小雨",\
"wind1":"东风转东北风小于3级","wind2":"东北风小于3级","wind3":"东北风小于3级","wind4":"东北风小于3级","wind5":"东北风小于3级","wind6":"东北风小于3级",\
"fx1":"东风","fx2":"东北风","fl1":"小于3级","fl2":"小于3级","fl3":"小于3级","fl4":"小于3级","fl5":"小于3级","fl6":"小于3级",\
"index":"较冷","index_d":"建议着厚外套加毛衣等服装。年老体弱者宜着大衣、呢外套加羊毛衫。",\
"index48":"较冷","index48_d":"建议着厚外套加毛衣等服装。年老体弱者宜着大衣、呢外套加羊毛衫。",\
"index_uv":"最弱","index48_uv":"最弱","index_xc":"不宜","index_tr":"适宜","index_co":"较舒适",\
"st1":"7","st2":"4","st3":"6","st4":"6","st5":"6","st6":"3","index_cl":"较不宜","index_ls":"不宜","index_ag":"极不易发"}}
'''
jsonDatas = json.loads(weatherInfomation)

rst = {}

city = jsonDatas["weatherinfo"]["city"]
tempF1 = jsonDatas["weatherinfo"]["tempF1"]
weather = jsonDatas["weatherinfo"]["img_title1"]
img = jsonDatas["weatherinfo"]["img1"]
fx = jsonDatas["weatherinfo"]["fx1"] #风向

rst['index'] = jsonDatas["weatherinfo"]["index"] #天气指数 #冷
rst['cy'] = jsonDatas["weatherinfo"]["index_d"] #穿衣指数 #建议....
rst['zw'] = jsonDatas["weatherinfo"]["index_uv"] #紫外线指数 #最弱
rst['xc'] = jsonDatas["weatherinfo"]["index_xc"] #洗车指数 #不宜
rst['tr'] = jsonDatas["weatherinfo"]["index_tr"] #旅游指数 #很适宜
rst['co'] = jsonDatas["weatherinfo"]["index_co"] #舒适度 #较舒适
rst['cl'] = jsonDatas["weatherinfo"]["index_cl"] #晨练指数 #较适宜
rst['ls'] = jsonDatas["weatherinfo"]["index_ls"] #晾晒指数 #不太适宜
rst['ag'] = jsonDatas["weatherinfo"]["index_ag"] #过敏指数 #不易发"

rst['temp1'] = jsonDatas["weatherinfo"]["temp1"] #接下来第 1 天的温度
rst['temp2'] = jsonDatas["weatherinfo"]["temp2"] #接下来第 2 天的温度
rst['temp3'] = jsonDatas["weatherinfo"]["temp3"]
rst['temp4'] = jsonDatas["weatherinfo"]["temp4"]
rst['temp5'] = jsonDatas["weatherinfo"]["temp5"]
rst['temp6'] = jsonDatas["weatherinfo"]["temp6"]

rst['weather1'] = jsonDatas["weatherinfo"]["weather1"] #接下来第 1 天的天气
rst['weather2'] = jsonDatas["weatherinfo"]["weather2"]
rst['weather3'] = jsonDatas["weatherinfo"]["weather3"]
rst['weather4'] = jsonDatas["weatherinfo"]["weather4"]
rst['weather5'] = jsonDatas["weatherinfo"]["weather5"]
rst['weather6'] = jsonDatas["weatherinfo"]["weather6"]
except:
print 'getCityWeatherDetail_SixDay Error'
return {}
else:
return rst

#返回dict类型
def getCityWeather_AllDay(cityID):
'''全天天气数据,返回'''

url = "http://www.weather.com.cn/data/cityinfo/" + str(cityID) + ".html"
try:
req=urllib2.Request(url)
stdout = urllib2.urlopen(url)
weatherInfomation = stdout.read().decode('utf-8')
print 'allday - ',weatherInfomation
#{"weatherinfo":{"city":"杭州","cityid":"101210101","temp1":"7℃","temp2":"2℃","weather":"多云转阴","img1":"d1.gif","img2":"n2.gif","ptime":"11:00"}}

jsonDatas = json.loads(weatherInfomation)

city = jsonDatas["weatherinfo"]["city"] #城市
temp1 = jsonDatas["weatherinfo"]["temp1"]#最高温度
temp2 = jsonDatas["weatherinfo"]["temp2"]#最低温度
weather = jsonDatas["weatherinfo"]["weather"]#天气信息,如“多云转晴”
img1 = jsonDatas["weatherinfo"]["img1"] # 图片,http://www.weather.com.cn/m/i/weatherpic/29x20/d1.gif
img2 = jsonDatas["weatherinfo"]["img2"] # 图片
ptime = jsonDatas["weatherinfo"]["ptime"]# 发布时间

except:
print "getCityWeather_AllDay Error"
return {}
else:
return {'high':temp1,'low':temp2,'weather':weather,'img':img1,'ptime':ptime}
pass #return
finally:
None

if __name__=="__main__":
"main function"

title_small = "【实时】"
#实时数据
dicRealTime = getCityWeather_RealTime(101210101)
current_temp = u'N/A'
current_wet = u'N/A'
current_wind_direction = u'N/A'
current_temp = dicRealTime['temp'] #温度
current_wet = dicRealTime['sd'] #湿度
current_wind_direction = dicRealTime['wd'] #风向
current_wind_strong = dicRealTime['ws'] #风力 '2级'
current_real_time = dicRealTime['time'] #时间getCityWeather_RealTime(101210101)

print current_temp,current_wet,current_wind_direction
#print title_small , twitter['message']

#for city in cityList_bsgs:
title_small = "【全天】"
#getCityWeather_AllDay(101210101)
#print title_small , twitter["message"]

title_small = "【六天】"
#getCityWeatherDetail_SixDay(101210101)
#print title_small , twitter["message"][/python]

 

 

 

 

 

 

作者:JarvisChu
原文链接:python 天气预报(v2.0)
版权声明:自由转载-非商用-非衍生-保持署名 | Creative Commons BY-NC-ND 3.0

发表评论