在大学慕课学习过python后,结课作业是让我们做出一个小项目,提供了很多方向,鉴于本人爬虫能力很弱😥,我选择基于环境云网站提供的API接口,实现了天气预报功能以及过去的天气数据分析功能,其中对于我来说比较困难的是如何实现覆盖全国的省市县下拉列表的实现,下面是我的实现思路🧐
1.处理数据表
在环境云网站我得到了全国的省市县的areaid.xlsx文件,如下。
- 第一步 首先我将上面的文件转换成了areaid.csv形式,然后利用python中的pandas的read_csv函数很方便的将.csv文件转换成了Dataframe数据结构。
pd.read_csv(file_path)
- 第二步 将得到的Dataframe的index属性设置为NAMEEN中的所有元素组成的一个列表,这样设置一方面是为了便于后来的处理,另一方面是因为Dataframe这种数据类型的index不支持中文,下面是我的实现代码。
csv_file = pd.read_csv(file_path) #file_path是areaid.csv文件的路径
list_index = [i for i in csv_file.NAMEEN]
csv_file.index = list_index #将Dataframe的index属性换成所有县区的汉语拼音
csv_file_once = csv_file.drop(['NAMEEN'], axis = 1) #去掉Dataframe中的NAMEEN元素
下面是处理后的效果
- 第三步得到省份和市区的列表 首先将Dataframe中的PROVCN元素取出来然后利用集合去掉重复的元素,最后将其处理成一个省份列表,市区的处理过程同上。
#省份的处理
list_P = csv_file_onece.PROVCN
Shengfen_once = set(i for i in list_P)
Shengfen_second = list(Shengfen_onece)
#市区的处理
list_D = csv_file_onece.DISTRICTCN
Shiqu_onece = set(i for i in list_D)
Shiqu_second = list(i for i in Shiqu_onece)
- 第四步(核心) 在这里说一下我在实现省事区多级嵌套下拉列表过程中对于数据关联的一些思考,我一开始认为实现多级嵌套需要用到多级嵌套字典,但是实现起来确实有一定的难度,加上网上也找不到相关的教程,于是我就换了一种思路,将两级嵌套字典,拆分成两个字典,这样实现起来就明显的简单许多。 首先我先实现了省份:市区和市区:县区的两个字典
# {省份:市区} 的实现
list_all_shiqu = [] #用来存放每个省份的对应市区的列表
for i in Shengfen_second:
csv_file_second = csv_file_onece.copy()
csv_file_second.index = [i for i in csv_file_second.PROVEN] #将Dataframe对象的index属性换成PROVEN元素
shenfen_pinyin = pinyin.get(i, format="strip", delimiter="") #调用pinyin包(需要install),将省份的汉字转换成拼音
csv_file_shiqu = csv_file_second.loc[shenfen_pinyin,'DISTRICTCN'] #利用loc函数截取Datafram对象中index== shenfen_pinyin 的片段
set_shiqu = set(csv_file_shiqu) #去掉市区元素中重复的部分
list_shiqu = [i for i in set_shiqu]
list_all_shiqu.append(list_shiqu) #将得到的市区数组添加到list_all_shiqu数组
dict1 = dict(zip(Shengfen_second,list_all_shiqu)) #打包生成{省份:市区}字典
#{市区:县区}
list1_xianqu_all = []
for i in Shiqu_second:
csv_file_second= csv_file_onece.copy()
csv_file_second.index = [i for i in csv_file_second.DISTRICTEN]
shiqu_pinyin = pinyin.get(i, format="strip", delimiter="")
csv_file_xianqu = csv_file_second.loc[shiqu_pinyin, 'NAMECN']
if type(csv_file_xianqu) is str: #避免csv_file_xianqu中只有一个元素
list_one_colume = [csv_file_xianqu]
list1_xianqu_all.append(list_one_colume)
else:
set_xianqu = set(csv_file_xianqu)
list_xianqu = [i for i in set_xianqu]
list1_xianqu_all.append(list_xianqu)
dict2 = dict(zip(Shiqu_second, list1_xianqu_all))
下面是实现的效果:
2.创建下拉列表
- 第一步 wxpython官网 首先需要导入wx库,这是一个跨平台的GUI库,可以帮助开发者实现快速的GUI开发,而且轻量级,很适合python环境下一些小型非商用项目的开发。 然后创建一个fram类,具体过程可以自行百度,这里就不过多赘述。
- 第二步 在fram类的初始化函数中创建一个panel。 同时创建一个sizer(对组件进行布局的一种算法) 这里创建的是一种BoxSizer,在窗口中纵向添加组件
codeSizer = wx.BoxSizer(wx.HORIZONTAL)
创建三个下拉列表框
proviceLable = wx.StaticText(panel, -1, "省份:") #省份的静态说明文本框
proviceComboBox = wx.ComboBox(panel, -1, value=list(dict1.keys())[0], choices=list(dict1.keys()),
style=wx.CB_READONLY) #省份的下拉文本框
cityLable = wx.StaticText(panel, -1, "市区:") #市区~
shiquComboBox = wx.ComboBox(panel, -1, value=dict1[list(dict1.keys())[0]][0],
choices=dict1[list(dict1.keys())[0]], style=wx.CB_READONLY) #市区~
value1 = dict1[list(dict1.keys())[0]][0] #这个变量用于得到省份字典的第一个key值所对应的value值,主要用于对县级下拉列表的初始化
xianquLable = wx.StaticText(panel, -1, "县区:") #县区~
xianquComboBox = wx.ComboBox(panel, -1, value=dict2[value1][0],
choices=dict2[value1], style=wx.CB_READONLY) #县区~
- 第三步 将创建的静态文本框和下拉文本框添加到sizer中
codeSizer.AddMany([
(proviceLable, 0, wx.ALIGN_RIGHT), (proviceComboBox, 0, wx.SHAPED)
, (cityLable, 0, wx.ALIGN_RIGHT), (shiquComboBox, 0, wx.SHAPED)
,(xianquLable, 0, wx.ALIGN_RIGHT), (xianquComboBox, 0, wx.SHAPED),
])
下面是添加后的效果
- 第四步 需要定义相应列表点击的响应函数
def __OnComboBoxSelected1(self, event): #省份列表点击的响应函数
currentProvinceIndex1 = self.__ProvinceComboBox.GetSelection()
if wx.NOT_FOUND == currentProvinceIndex1 :return
value1 = self.__ProvinceComboBox.GetItems()[currentProvinceIndex1]
cityList = self.__SecityDict[value1]
self.__CityComboBox.SetItems(cityList)
self.__CityComboBox.SetValue(cityList[0])
self.__OnComboBoxSelected2(self)
def __OnComboBoxSelected2(self, event): #市区列表点击的响应函数
currentShiquIndex = self.__CityComboBox.GetSelection()
if wx.NOT_FOUND == currentShiquIndex: return
value = self.__CityComboBox.GetItems()[currentShiquIndex]
cityList = self.__SecityDict1[value]
self._XianquCombobox.SetItems(cityList)
self._XianquCombobox.SetValue(cityList[0])
def __OnComboBoxSelected3(self,event): #响应县区下拉文本框点击的响应函数
currentXianquIndex= self._XianquCombobox.GetSelection()
value = self._XianquCombobox.GetItems()[currentXianquIndex]
self._cityname = value
- 第五步 利用panel的Bind函数将列表的点击事件和,响应各级下拉列表框点击的响应函数联系起来
#定义一级列表被点击时响应二级列表和三级列表的刷新事件
self.__ProvinceComboBox = proviceComboBox
self.__SecityDict = dict1
self.__CityComboBox = shiquComboBox
panel.Bind(wx.EVT_COMBOBOX, self.__OnComboBoxSelected1, proviceComboBox,)
#定义二级列表被点击时响应三级列表的刷新事件
self.__SecityDict1 = dict2
self._XianquCombobox = xianquComboBox
panel.Bind(wx.EVT_COMBOBOX, self.__OnComboBoxSelected2, shiquComboBox,)
#定义三级列表被点击时响应的事件
panel.Bind(wx.EVT_COMBOBOX, self.__OnComboBoxSelected3, xianquComboBox,)
初始状态下的列表框
当我点击了省份下拉列表框时,效果如下
市区
响应后
以上内容就是我实现省市县的级连下拉列表框的所有内容
下面的内容是关于我所做的环境云项目的介绍 这个项目主要实现了五个功能模块
-
天气预报
实现对所选城市的未来七天的天气预报的查询
-
过去24小时天气
查询指定城市过去24小时的天气情况
-
月度天气
查询指定城市指定年份的月度天气状况
-
日天气
查询指定城市指定日期的天气状况
-
对天气状况进行分析
对天气预报的情况进行分析
对过去24小时的天气进行分析
对月度天气进行分析
文章开头有我的github的网址,可以找到源代码,如果有更好的实现方式,欢迎在评论区留言,我们一起共同学习交流。