在上一篇:
中,我介绍了wxPython的事件处理机制、如何绑定按钮事件,并且实现了“更新”按钮的功能。在本篇中,我将会实现“设置”按钮的功能。“设置”按钮的功能比较多,实现起来比较复杂,而且如何使“设置”面板即美观又方便,考虑过很多种方法,最终确定了一种自认为比较简洁方便的方案。本篇还涉及到wx.ListCtrl(列表)控件的使用、弹出菜单、SQLite数据库等方面的知识。这些我也是边学边用,现学现卖,不足之处大家勿喷~本文出自三思之旅博客http://think3t.iteye.com,转载请注明出处。
首先,在上一篇中,我们已经给“设置”按钮绑定了处理器方法。
self.Bind(wx.EVT_BUTTON,self.OnConfig,self.setupBtn) #设置按钮绑定事件处理器 def OnConfig(self,event): '''处理器方法''' cfgFrame=CfgFrame(self) #打开配置窗口 cfgFrame.Show(True) #显示配置窗口
我的设计是,点击“设置”按钮,打开“设置”窗口。先给大家看下设置窗口实际效果,再一步步来实现它。
先说下整体布局:整体是个垂直方向的BoxSizer,共有3行,第一行是一个StaticText控件,显示“当前用户”4个字;第二行是一个列表控件(ListCtrl),列出了当前所有用户的信息;第三行是一个水平方向StaticBoxSizer,就是“定时发送”复选框(CheckBox)、3个下拉框(Choice)表示时分秒以及2个StaitcText显示两个冒号。下图我的把3行内容分别用红框圈住,看起来更加直观。至于如何实现这种布局,我就不详说了,前面的篇幅里有。
从图中我们还可以看到,列表中还有右键菜单,有3个菜单项,分别是“增加”,“删除”,“设为主城市”,功能分别是增加用户、删除用户、把所选用户的城市设为主城市。主城市的作用其实就是软件运行时显示主城市的天气信息。主城市用户项在列表中的文字颜色是红色,以区别于其他的用户项。StaticText控件很简单,前边也用到过,这里不再赘述。下面重点说一下之前没用过的控件:列表、复选框、下拉框。
首先是列表,其构造方法是
wx.ListCtrl(parent, id, pos=wx.DefaultPosition, size=wx.DefaultSize, style=wx.LC_REPORT, validator=wx.DefaultValidator, name='listCtrl')
各参数的意义和之前的控件一样,这里说一下style。一共有4种类型的列表,分别是:
- wx.LC_ICON:图标模式,使用大图标
- wx.LC_LIST:列表模式
- wx.LC_REPORT:报告模式
- wx.LC_SMALL_ICON:图标模式,使用小图标
此处我们使用的是报告模式,报告模式还有3种显示样式:
- wx.LC_HRULES:在列表的行与行间显示网格线(水平分隔线)
- wx.LC_NO_HEADER:不显示列标题
- wx.LC_VRULES:显示列与列之间的网格线(竖直分隔线)
本程序中我们构造的是显示水平、垂直分隔线并显示列标题的报告模式的列表,构造方法如下:
# 显示水平、竖直分隔线的报告模式的列表 self.list = wx.ListCtrl(self.panel, -1, style=wx.LC_REPORT | wx.LC_HRULES | wx.LC_VRULES)
构造了列表之后就要往列表里面插入内容。首先创建4个列,依次为序号、邮箱、城市、备注,然后依次插入用户信息即行,每行是一个用户的信息。创建列的语法是
InsertColumn(col, heading, format=wx.LIST_FORMAT_LEFT, width=-1)
其中col是新列的索引,最左边是0,接下来依次为1、2、3、……;heading是列标题;format控制列中文本的对齐方式,取值有:wx.LIST_FORMAT_CENTER、wx.LIST_FORMAT_LEFT和wx.LIST_FORMAT_RIGHT;width是列的初始显示宽度(以像素为单件),默认-1表示根据内容自动控制。本程序中创建的4个列的具体实现是:
# 创建4个列 self.list.InsertColumn(0, u'序号', format=wx.LIST_FORMAT_LEFT, width=50) self.list.InsertColumn(1, u'邮箱', format=wx.LIST_FORMAT_LEFT, width=150) self.list.InsertColumn(2, u'城市', format=wx.LIST_FORMAT_LEFT) self.list.InsertColumn(3, u'备注', format=wx.LIST_FORMAT_LEFT)
要增加一个新行,使用InsertItem()这类的一种方法。具体所用的方法依赖于你所插入的项目的类型。如果你仅仅插入一个字符串到列表中,使用InsertStringItem(index, label),其中的index是要插入并显示新项目的行的索引,label是显示的字符串,这里实际上只是插入了一个新行并把第一列的文本设置为label。要在另外的列中设置字符串,可以使用方法SetStringItem(index, col,label,imageId=-1)。参数index和col是你要设置的单元格的行和列的索引。你可以设定col为0来设置第一列,但是参数index必须对应列表控件中已有的行——换句话说,这个方法只能对已有的行使用。参数label是显示在单元格中文本,参数imageId是图像列表中的索引(如果你想在单元格中显示一个图像的话可以设置这个参数,我们不需要显示图像,所以不用管这个参数)。本文出自三思之旅博客http://think3t.iteye.com,转载请注明出处。
本程序中插入用户信息是这样实现的:先从SQLite数据库中获取用户信息,然后每个用户信息增加一行,并依次把第一列设置为行序号,然后把具体用户信息插入其他列。具体代码如下:
# 获取用户信息,得到一个三元组列表 userInfos = self.searcher.getUserInfo() # 从第一行开始,第一行的索引为0 row = 0 # 依次插入用户信息 for (mail, city, note) in userInfos: # 每个用户信息增加一个行,并把首列显示为行序号,从1开始 self.list.InsertStringItem(row, str(row + 1)) # 再把接下来3列依次插入用户信息(邮箱、城市、备注) self.list.SetStringItem(row, 1, mail) self.list.SetStringItem(row, 2, city) self.list.SetStringItem(row, 3, note) # 如果当前用户是主城市,则显示为红色,并记录行号 if self.searcher.isMainCity(mail, city): self.list.SetItemTextColour(row, wx.RED) self.main_city = row # 下一用户行号加1 row += 1 # 全部用户信息插入完成后记录最后一行索引 self.totaluser = row # 第二列(邮箱)根据内容自动调整列宽 self.list.SetColumnWidth(1, wx.LIST_AUTOSIZE) # 默认会选中第一行内容,此处我们使第一行不被选中 self.list.SetItemState(0, 0, wx.LIST_STATE_SELECTED)
代码中用到了searcher这个类,这个类是我自己写的从数据库中读写用户信息的类,以后会有介绍。
现在列表中有信息了。接下来我们给列表增加右键菜单,首先绑定弹出菜单事件处理器。
# 给列表增加右键菜单 self.list.Bind(wx.EVT_CONTEXT_MENU, self.OnShowPopup)
该右键菜单有3个菜单项,“增加”、“删除”、“设为主城市”,其中“删除”、“设为主城市”我希望在选中某行的时候才显示出来。事件处理器代码如下:
def OnShowPopup(self, event): # 创建一介菜单 self.popupmenu = wx.Menu() # 添加“增加”菜单项,这个菜单项一直都有 item_add = self.popupmenu.Append(-1, u'增加') # “增加”菜单项绑定处理器方法 self.list.Bind(wx.EVT_MENU, self.OnAdd, item_add) # 当选中某行时才显示“删除”、“设置主城市”菜单 if self.list.GetFirstSelected() != -1: # 添加“删除”菜单项 item_del = self.popupmenu.Append(-1, u'删除') # “删除”菜单项绑定处理器方法 self.list.Bind(wx.EVT_MENU, self.OnDel, item_del) # 添加“设为主城市”菜单项 item_setMain = self.popupmenu.Append(-1, u'设为主城市') # “设为主城市”菜单项绑定处理器方法 self.list.Bind(wx.EVT_MENU, self.OnSetMain, item_setMain) # 获取事件发生的坐标,即点击右键的地方,这个坐标是相对于整个屏幕来计算的 pos = event.GetPosition() # 把坐标转换为以本程序界面为基准的坐标 pos = self.list.ScreenToClient(pos) # 在点击右键的地方显示右键菜单
接下来实现各菜单项的功能。单击“增加”菜单项打开一个增加用户对话框,用户根据提示填写相关信息后点击确实即往数据库中增加用户信息,并将新用户信息显示在列表中,点击取消则直接回到“设置”界面。增加用户对话框如下图所示:
这个对话框是我自己用Frame实现的,整体布局是一个竖直方向的BoxSizer,一共3行,每行都是一个水平方向的BoxSizer。说到这里不得不赞一句,wxPython的BoxSizer实在是太好用了!一般几个嵌套的BoxSizer就可以实现比较复杂的布局,因此推荐布局首选BoxSizer。此处用到的新的控件是下拉框(Choice)和复选框(CheckBox),重点说一下。本文出自三思之旅博客http://think3t.iteye.com,转载请注明出处。
下拉框的构造方法为:
wx.Choice(parent, id, pos=wx.DefaultPosition, size=wx.DefaultSize, choices=None, style=0, validator=wx.DefaultValidator, name=”choice”)
参数choices是个列表,用于初始化下拉框的各项。wx.Choice没有专门的样式,但是它有独特的命令事件:EVT_CHOICE。常用的方法有GetSelection():返回当前选中项的索引;GetStringSelection():返回当前选中项的文本内容;SetSelection(n):设置索引为n的项被选中,不会触发EVT_CHOICE事件。
我已经把全国各省市县区的相关信息存入数据库中了,实现“增加用户”对话框中的三个下拉框(依次为省、市、区/县时,先从数据库中导出相关信息,并生成省、市、区/县的列表,再用相应的列表初始化相应的下拉框。省、市的下拉框都绑定了EVT_CHOICE事件,这样更改省份的时候,市和区/县的下拉框内容随之更改;更改市的时候,区/县的下拉框内容随之更改。默认显示城市为北京。具体代码如下:
# 从数据库中导出省、市、县信息并存在3个列表中 provList = self.searcher.listProvs() cityList = self.searcher.listCityOfProv(u'北京') zoonList = self.searcher.listZoonOfCity(u'北京', u'北京') # 创建省份下拉框,默认显示北京,绑定EVT_CHOICE事件处理器 self.provCho = wx.Choice(self.panel, -1, choices=provList) self.provCho.SetSelection(0) self.Bind(wx.EVT_CHOICE, self.OnProvSel, self.provCho) # 创建市下拉框,默认显示北京,绑定EVT_CHOICE事件处理器 self.cityCho = wx.Choice(self.panel, -1, choices=cityList) self.cityCho.SetSelection(0) self.Bind(wx.EVT_CHOICE, self.OnCitySel, self.cityCho) # 创建区/县下拉框,默认显示北京 self.zoonCho = wx.Choice(self.panel, -1, choices=zoonList) self.zoonCho.SetSelection(0) def OnProvSel(self, event): '''省份下拉框EVT_CHOICE事件处理器''' prov = event.GetString() # 获取当前选中的省份名称 cityList = self.searcher.listCityOfProv(prov) # 获取当前省份的市信息列表 self.cityCho.SetItems(cityList) # 更新市下拉框内容 self.cityCho.SetSelection(0) # 默认显示省会城市 city = self.cityCho.GetStringSelection() # 获取当前市的名称 zoonList = self.searcher.listZoonOfCity(prov, city) # 获取当前市的区/县信息列表 self.zoonCho.SetItems(zoonList) # 更新区/县下拉框内容 self.zoonCho.SetSelection(0) # 默认显示市区 def OnCitySel(self, event): '''市下拉框EVT_CHOICE事件处理器''' prov = self.provCho.GetStringSelection() # 获取当前选中的省份名称 city = event.GetString() # 获取当前市的名称 zoonList = self.searcher.listZoonOfCity(prov, city) # 获取当前市的区/县信息列表 self.zoonCho.SetItems(zoonList) # 更新区/县下拉框内容 self.zoonCho.SetSelection(0) # 默认显示市区
接下来说一下复选框(CheckBox)。CheckBox的构造方法为:
wx.CheckBox(parent, id, label, pos=wx.DefaultPosition, size=wx.DefaultSize, style=0, name=”checkBox”)
label参数是复选框的标签文本。复选框没有样式标记,但是它们产生属于自己的独一无二的命令事件:EVT_CHECKBOX。wx.CheckBox的开关状态可以使用GetValue()和SetValue(state)方法来访问,并且其值是一个布尔值。IsChecked()方法等同于GetValue()方法,只是为了让代码看起来更易明白。本程序中实现复选框的代码为:
self.mcityChk = wx.CheckBox(self.panel, -1, label=u'主城市')
接下来讲一下”确定”和“取消”两个按钮的功能实现。“确实”按钮的功能即将用户信息添加进数据库并显示在列表中,其中还对邮箱地址格式进行了简单判断,邮箱为空或格式不合法不会添加用户信息并提示用户重新输入。“取消”按钮功能更简单,直接关闭“增加用户”对话框即可。具体代码如下:
self.OKBtn = wx.Button(self.panel, wx.ID_OK, label=u'确定') self.cancelBtn = wx.Button(self.panel, wx.ID_CANCEL, label=u'取消') self.Bind(wx.EVT_BUTTON, self.OnOK, self.OKBtn) self.Bind(wx.EVT_BUTTON, self.OnCancel, self.cancelBtn) def OnOK(self, event): '''确定按钮功能实现''' prov = self.provCho.GetStringSelection() # 获取当前选中的省份名称 city = self.cityCho.GetStringSelection() # 获取当前市的名称 zoon = self.zoonCho.GetStringSelection() # 获取当前区/县的名称 cityCode = self.searcher.getCityCode(prov, city, zoon) # 从数据库中获取当前选中的城市代码 mailAddr = self.mailTxt.GetValue() # 获取邮箱地址 # 判断邮箱地址格式是否合法 if mailAddr == '': # 如果邮箱为空,则状态栏提示'请输入邮箱地址!' self.stBar.SetStatusText(u'请输入邮箱地址!') elif re.match(r'[\w\.]+@\w+\.\w+', mailAddr): # 邮箱地址合法,则执行添加用户动作 if self.mcityChk.IsChecked(): # 如果勾选“主城市”复选框,则新增加的用户为主城市 self.searcher.clearMainCity() # 数据库中只能有一个主城市,所以要先清除原主城市标记 self.searcher.addItem(table='userInfo', values=(mailAddr, cityCode, 1, zoon)) # 把用户信息写入数据库 else: self.searcher.addItem(table='userInfo', values=(mailAddr, cityCode, 0, zoon)) self.stBar.SetStatusText(u'用户%s添加成功!' % mailAddr) # 状态栏提示用户添加成功 row = self.Parent.totaluser # 获取原来列表中最后一行索引号 # 将新增加的用户信息添加在列表里 self.Parent.list.InsertStringItem(row, str(row + 1)) self.Parent.list.SetStringItem(row, 1, mailAddr) self.Parent.list.SetStringItem(row, 2, cityCode) self.Parent.list.SetStringItem(row, 3, zoon) if self.mcityChk.IsChecked(): # 如果勾选“主城市”复选框,则新增加的用户为主城市 # 将原主城市文字颜色设置为黑色 self.Parent.list.SetItemTextColour(self.Parent.main_city, wx.BLACK) # 将新主城市文字颜色设置为红色 self.Parent.list.SetItemTextColour(row, wx.RED) # 记录新主城市所在行 self.Parent.main_city = row # 将新增加的行设置为选中状态 currentSelected = self.Parent.list.GetFirstSelected() if currentSelected != -1: self.Parent.list.SetItemState(currentSelected, 0, wx.LIST_STATE_SELECTED) self.Parent.list.SetItemState(row, wx.LIST_STATE_SELECTED, wx.LIST_STATE_SELECTED) self.Parent.totaluser += 1 # 当前用户总数加1 self.Close() # 操作完成,关闭“增加用户”对话框 else: # 如果邮箱地址格式合法,则状态栏提示'邮箱地址格式错误!' self.stBar.SetStatusText(u'邮箱地址格式错误!') def OnCancel(self, event): '''点击取消按钮则关闭对话框''' self.Close()
至此为止,列表的“增加”菜单项的功能已经实现了。接下来实现”删除“菜单项的功能。点击”删除“菜单项,要执行以下动作:获取选中的行的用户信息,然后从数据库中删除该用户信息;还要从列表中删除相应的行,同时为保持行序号的连续性,被删除行以下的行序号要重新调整;此外,如果被删除的行是主城市,还要重新指定主城市,我这里把第一行设置为主城市。同时,由于删除操作不可撤销,所以弹出警告框,给用户确认。具体代码如下:
def OnDel(self, event): '''“删除”菜单项的功能实现''' # 弹出警告框,供用户确认 retCode = wx.MessageBox(u'确定要删除该用户?\n请注意:该操作不可撤销!', u'请确认删除', wx.YES_NO | wx.ICON_QUESTION) # 用户点击“是”才执行删除动作 if retCode == wx.YES: row = self.list.GetFirstSelected() # 获取当前选中的行索引 mail = self.list.GetItemText(row, 1) # 从选中行中取得邮箱信息 city = self.list.GetItemText(row, 2) # 从选中行中取得城市信息 self.list.DeleteItem(row) # 删除列表中的行 if self.searcher.isMainCity(mail, city): # 如果被删除的是主城市,则设置删除之后列表第一行为主城市 self.list.SetItemTextColour(0, wx.RED) self.searcher.setMainCity(self.list.GetItemText(0, 1), self.list.GetItemText(0, 2)) self.searcher.delItem(mail, city) # 清除数据库中相应信息 self.totaluser -= 1 # 总用户数量减1 for i in range(row, self.totaluser): # 重新调整被删除行以后的行序号 self.list.SetItemText(i, unicode(i + 1))
最后还剩下“设为主城市”菜单项的功能实现。这个其实就更简单了,无非就是删除原主城市标记,设置新主城市标记。当然,数据库和列表都要进行处理。具体代码如下:
def OnSetMain(self, event): self.searcher.clearMainCity() # 清除原主城市 row = self.list.GetFirstSelected() # 获取选中的行索引 mail = self.list.GetItemText(row, 1) # 获取邮箱地址 city = self.list.GetItemText(row, 2) # 获取城市信息 self.searcher.setMainCity(mail, city) # 设置新的主城市 self.list.SetItemTextColour(self.main_city, wx.BLACK) # 原主城市行字体回归黑色 self.list.SetItemTextColour(row, wx.RED) # 新主城市字体设置为红色 self.main_city = row # 更新主城市行号全局变量
至此,列表部分的相关功能都已经完成。目前还剩下最下边设定定时发送部分的功能。这一部分也很简单,一个复选框,3个下拉框。复选框、下拉框前边都已介绍过,这里也无需详述。复选框绑定了wx.EVT_CHECKBOX事件,当勾选复选框时,3个下拉框可用;否则不可用。
self.setTimeChk = wx.CheckBox(self.panel, -1, label=u'定时发送') self.Bind(wx.EVT_CHECKBOX, self.OnSetTimeChk, self.setTimeChk) def OnSetTimeChk(self, event): # 勾选复选框时,3个下拉框可用 if self.setTimeChk.IsChecked(): self.hourCho.Enable() self.minuteCho.Enable() self.secondCho.Enable() # 未勾选复选框时,3个下拉框不可用 else: self.hourCho.Disable() self.minuteCho.Disable() self.secondCho.Disable()
这样,整个设置窗口的内容基本介绍完成了。这里还有个问题,如何保存定时信息?我打算使用cfg.ini文件保存定时信息。python自带读写ini文件的库,不过不太好用,我使用dict4ini库(项目主页:http://code.google.com/p/dict4ini/),用这个库操纵ini文件就和操纵字典类型一样,非常好用。如作者自己所介绍的
我的设计是,关闭设置窗口的时候,自动保存定时信息。为此,就要绑定CfgFrame的wx.EVT_CLOSE事件。代码很简单,如下:
self.Bind(wx.EVT_CLOSE, self.OnClose) # 配置窗口关闭时保存定时信息 def OnClose(self, event): '''关闭配置窗口时都会保存定时信息''' if self.setTimeChk.IsChecked(): # 如果勾选定时发送复选框,就将Timer设置为1 self.myIni.Config.Timer = 1 else: # 如果未勾选定时发送复选框,就将Timer设置为0 self.myIni.Config.Timer = 0 # 保存时分秒信息 self.myIni.Config.Hour = self.hourCho.GetSelection() self.myIni.Config.Minute = self.minuteCho.GetSelection() self.myIni.Config.Second = self.secondCho.GetSelection() # 保存ini文件 self.myIni.save() # 销势设置窗口 self.Destroy()
cfg.ini文件的内容如下:
[Config] Timer = 0 Hour = 8 Minute = 5 Second = 0
Timer=0不启用定时,Timer=1启用定时发送。有了cfg.ini文件,定时信息就可以保存起来。当然,每次程序运行时都要读取这个定时信息,并根据定时信息设置定时发送复选框的状态和时分秒下拉框的值。
# 从cfg.ini文件中读取定时信息 isTimerOn = self.myIni.Config.get('Timer', 0) timer_hour = self.myIni.Config.get('Hour', 8) timer_minute = self.myIni.Config.get('Minute', 5) timer_second = self.myIni.Config.get('Second', 0) # 根据定时信息设置时分秒下拉框的值 self.hourCho.SetSelection(timer_hour) self.minuteCho.SetSelection(timer_minute) self.secondCho.SetSelection(timer_second) # 根据Timer的值设置定时发送复选框的状态以及时分秒下拉框是否可用 if isTimerOn: self.setTimeChk.SetValue(True) self.hourCho.Enable() self.minuteCho.Enable() self.secondCho.Enable() else: self.setTimeChk.SetValue(False) self.hourCho.Disable() self.minuteCho.Disable() self.secondCho.Disable()
到此为止,本篇文章可以结束了。本篇中用到了searcher这个我自己写的用来读写SQLite数据库的类,下一篇中我会进行介绍。还有虽然现在已经可以保存定时信息,但程序还不能定时发送,这一部分的功能也还没实现,我会在以后的篇幅中实现它。请大家继续关注~ 本文出自三思之旅博客http://think3t.iteye.com,转载请注明出处。
相关推荐
天气预报信息——易语言模块 天气预报信息——易语言模块
在Qt编程中,创建用户界面(UI)是十分常见的任务,而通过点击按钮来打开新的窗口是许多应用程序的基础功能。这篇教程将引导你了解如何在Qt中实现这一操作,主要涉及的知识点包括信号与槽机制、QWidgets类的使用以及...
人工智能技术能否提高地面气温预报的精度——记AI Challenger 2018全球天气预报挑战赛.pdf
接口课程设计——实现特定功能的键盘及LED显示 可以实现以下功能: 1. 按1键显示年; 2. 按2键显示月日; 3. 按3键显示GOOD ; 4. 按4键数码管由左到右字符“0”循环显示。 5.自行设计特效显示功能。
本示例主要关注如何实现一个特殊的Swing按钮功能:允许用户通过鼠标拖动来改变按钮在窗口中的位置。 首先,我们需要创建一个自定义的JButton子类,这个子类将扩展Swing的JButton类,并添加额外的拖动功能。我们可以...
"VB按钮控件大全——经典按钮"是一个集合,提供了多种不同风格和功能的按钮控件,可以丰富你的VB应用程序的设计和用户体验。 1. **控件的添加方式**: - 首先,你需要将压缩包中的所有`.oca`和`.ocx`文件解压缩到...
HTML概述 单选按钮 HTML概述——单选按钮
通过调用webservice显示全国天气预报
该项目的系列介绍文章:https://blog.csdn.net/weixin_50964512/article/details/125710864
微信小程序——创客+实现大量功能,推荐研究(截图+源码).zip 微信小程序——创客+实现大量功能,推荐研究(截图+源码).zip 微信小程序——创客+实现大量功能,推荐研究(截图+源码).zip 微信小程序——创客+实现...
在这个天气预报应用中,我们可以学习到如何使用这两种语言之一来构建一个功能完备的应用。Swift是苹果于2014年推出的现代编程语言,语法简洁且安全,而Objective-C则更为传统,广泛用于早期的iOS开发。源码将展示这...
├─05 实战Google Maps API之三——地图天气预报服务 │ ├─5.1 在Google地图上显示天气预报 │ │ ├─5.1.2 利用Google AJAX Feed API加载RSS文档 │ │ └─5.1.3 YWeather()类的构造 │ └─5.2 │ └─...
Iphone开发系列源码——多功能播放器源码Iphone开发系列源码——多功能播放器源码Iphone开发系列源码——多功能播放器源码Iphone开发系列源码——多功能播放器源码Iphone开发系列源码——多功能播放器源码Iphone开发...
穆勒产品介绍——A22按钮指示灯ppt,穆勒产品介绍——A22按钮指示灯
这个名为"安卓Android源码——中文天气预报程序.zip"的压缩包文件,显然是一个包含了一个实现中文天气预报功能的Android应用源代码的项目。通过分析这个项目,我们可以深入学习Android应用程序开发,特别是关于数据...
———————————————— 版权声明:本文为CSDN博主「Android毕业设计源码」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。 原文链接:...
"IOS应用源码——闹钟加天气预报.rar"是一个示例项目,展示了如何将这两种功能整合到一个应用程序中。这个压缩包包含了一个完整的源代码实现,对于iOS开发者来说,它是一个学习和参考的宝贵资源。 首先,我们要关注...
第10章 情景10——实现用户登录和注册功能.ppt
Android源码——天气预报源码.zip
【第一部分】历史文章: ...Android学习笔记(五)——Toast提示、Dialog对话框、Menu菜单 Android学习笔记(六)——自定义ListView布局+AsyncTask异步任务 Android学习笔记(七)——数据存储(共享参数Share