经过前面几期的努力,我们做了这些事:
- 学习使用 Popup、Text、Edit、Button,创建视窗;
- 处理视窗的返回值:event 和 values,它们在一个 tuple 中;
- 用 requests 库请求网络资源——天气预报接口;
- 做了一个简单的天气预报工具;
- 让程序活的更长,变成持久化程序。
相比最开始学习 Python 只能得到一个黑窗输出一些字符,真的是已经相当 “现代化”了!
使用更专业的工具
之前我们的代码很多都托管在 repl.it 上,为了:
- 免除 Python 环境搭建之苦;
- 减少不一致性,确保同样的代码可以得到相同的结果,因为我们用的是同一套在线环境。
但是这个环境有点问题,对中文支持不好,还有点慢,而且 GUI 程序主要是在个人电脑上运行。我相信通过这么久的使用,对你来说安装 Python3 已经不再那么困难了。
安装好 Python3 以后,你就可以进入命令行输入
pip install PySimpleGUI
pip install requests
安装所需要的库。要记住:第三方库真的不在你的计算机里,在 “第三方” 那里。使用它们前一定要先安装,否则在代码中 import xxx 执行的时候就会报错 “No module named xxx”。
然后再安装 pycharm 或者 visual studio code,这些工具是更智能的开发工具,它会自动找到已经安装好的 Python。如果安装遇到问题,借助百度一般会得到很好的解决。
TIPS
我使用的是 visual studio code,如果你不确定,最好与我保持一致,也安装 visual studio code。
总之,是时候认真的编程了,在你的电脑上写程序、调试程序、使用程序,像一个真正的本地程序一样。
本地运行上一节代码
当你安装好 Python3,并且安装了 pycharm 或 visual studio code 之一作为开发工具,那么请新建一个目录 getWeatherTool,在其中创建一个 main.py 文件,粘贴下面的代码,这些代码是 上一节 的成果:
import PySimpleGUI as sg
import requests
import json
def get_weather(city):
# 在线环境不支持中文输入,所以我改用城市编号的接口,如果你在电脑上开发,就不受影响
r = requests.get("http://wthrcdn.etouch.cn/weather_mini?citykey=" + city)
result = json.loads(r.text)
return result["data"]["forecast"][0]["type"]
# 让所有文本居中
sg.SetOptions(text_justification='center')
# 蓝图不需要放到循环中
layout = [
[ sg.Text("City", size = (20, 1)), sg.Input(key = "-CITY-") ],
[ sg.Text("Weather", size = (20, 1)), sg.Input(key = "-WEATHER-") ],
[ sg.Button("Submit")]
]
# 视窗也只需要创建一次,不要放到循环里
window = sg.Window("Weather App", layout)
while True:
event, values = window.read()
print(event, values)
# 当点击 window 右上角的 X,event 是 None,此时应当退出循环
if event is None:
break
# values 是一个字典,访问可输入组件的 key(定义蓝图时指定了这个参数)可以获得组件的输入
city = values["-CITY-"]
weather = get_weather(city)
print(weather)
# 找到天气输入框
weather_wind = window["-WEATHER-"]
# 将天气更新到输入框
weather_wind.update(weather)
# 程序已经不会直接退出了,下一行就不需要了
# window.read()
# 当退出循环的时候,就是程序退出之时,关掉 window
window.close()
点击调试运行就可以看到结果了,记住,现在用的天气预报接口里,城市要填写编号,北京的编号是 101010100。
hu~ 北京的雾霾真是挥之不去~
一点改进
下面做一点改进,城市名称使用中文。
由于之前使用的是在线编辑环境,对中文支持不好,所以使用城市编码的形式。只要更换一个接口,就可以支持中文城市名查询了。
修改这个函数,使用新的接口:
def get_weather(city):
# 在线环境不支持中文输入,所以我改用城市编号的接口,如果你在电脑上开发,就不受影响
# 注释掉旧接口,不再使用城市编码查询天气
# r = requests.get("http://wthrcdn.etouch.cn/weather_mini?citykey=" + city)
r = requests.get("http://wthrcdn.etouch.cn/weather_mini?city=" + city)
result = json.loads(r.text)
return result["data"]["forecast"][0]["type"]
TIPS
看出来使用函数的好处了吧。 当要修改某个功能的时候,只要修改一个函数就可以。如果不用函数,就需要在代码各处修改,很麻烦,最糟糕的是容易出错。
再试着运行一次看看!这次我们输入城市名称就可以了,非常棒!
看,很多城市都有雾霾,武汉倒是多云,不错~
所有人都喜欢选择题
小时候考试对我一直都是梦魇,现在偶尔也会被惊醒。
即便如此,我对选择题也抱有特别对好感,即使完全不会也可以用 “学渣口诀” 蒙一个答案。
NOT TIPS
学渣口诀:
不是 A,就是 B,不会就蒙 C 和 D。
三长一短就选最短, 三短一长选最长,两长两短就选 B,参差不齐 C 无敌。
对于用户也是一样,选择要比填空更加友好。我们使用 Combo 替换 layout[0] 中的 Input。Combo 就是下拉框。
layout = [
#[ sg.Text("City", size = (20, 1)), sg.Input(key = "-CITY-") ],
[ sg.Text("City", size = (20, 1)), sg.Combo(("北京", "上海", "深圳"), size=(10, 1), default_value="上海", key = "-CITY-")]
[ sg.Text("Weather", size = (20, 1)), sg.Input(key = "-WEATHER-") ],
[ sg.Button("Submit")]
]
注意到 Combo 的初始化参数多了一些:
- 第一项参数是一个 tuple,是下拉框里所有的选项,这里列出了 3 个城市。
- 为了显示所有下拉框内容,我们将 size 指定为 (10, 1), 10 个英文字符宽,一个字符高。
- 再没有选中的时候,Combo 默认显示 default_value 中的值。
再看看结果:
成功的把填空题变成了选择题,对我这样的 “学渣” 实在是太照顾了。
TIPS
其实在用户心理中,从填空到选择的变化,引起的是用户决策成本的变化:选择要比提建设意见消耗的脑细胞少的多,成本耕地,用户会觉得更舒适。
对用户好一点,记住,这是对软件开发者最重要的建议!可能比写代码更重要。
没有最懒,只有更懒!
那就再宠爱一点用户咯,送佛送上天嘛!记得在介绍 window.read() 的时候,我们提到过 Button 只是触发 read 函数返回的组件之一,其他的各种可输入组件都可以!比如这里的 Combo 组件被选中的时候。
但是需要做一点准备工作:
layout = [
#[ sg.Text("City", size = (20, 1)), sg.Input(key = "-CITY-") ],
[ sg.Text("City", size = (20, 1)), sg.Combo(("北京", "上海", "深圳"), size=(10, 1), default_value="上海", change_submits=True, key = "-CITY-")],
[ sg.Text("Weather", size = (20, 1)), sg.Input(key = "-WEATHER-") ] #,
#[ sg.Button("Submit")]
]
我们为 Combo 增加了 change_submits=True,意思是当它发生变化的时候,要提交 event。
这样 layout[2] 中的 Button 其实就不需要了。每次 Combo 发生变化的时候,我们直接执行 Submit 按钮触发的逻辑就行了。
我们原来的代码会接受除了 退出(event is None) 外所有 event,所以到底是 Butto 还是 Combo 触发的就没所谓,只要触发 read 函数就行,代码也无需做更多更改。
来吧,成败在此一举!
行了!胸dei~ 我们还减少了一个按钮,这意味着用户可以少一次点击,真不错!
TIPS
一种软件作品哲学,“少既是多“。
其实不止对于写程序,对职业、爱好、甚至人生,这都是一个不错的哲学,“大而全”好处没那么多,不如试试 “小而美”, 聚焦那些重要的小事儿上。
总结
今天内容有点紧凑啊,我并不打算做奶妈,每一步都点拨到位。学习中遇到困难,借助强大的搜索引擎,通过自己的努力解决它,才是真正的学习之路吧。
今天成果满满:
- 在本地搭建了开发环境
- 使用现代化的开发工具(IDE),推荐 pycharm 或者 visual studio code。
- 在天气预报小工具中使用中文,
- 和下拉选择框,
- 另外取消了 Submit 按钮,整个界面十分清爽!
明天继续咯!