虽然用着同样的语言,当我们执行不同的编程任务时,就如同身处不同的世界。我们学习python语言基础时,所处的是最简单的控制台世界。现在,让我们进入一个稍微复杂一些,但更具表现力的世界:窗口世界。窗口世界独立于语言之外而存在着,很多语言都可以进行窗口编程,有了前面关于python语言的基本概念,我们已经可以用python语言来理解这个世界了。
让我们首先了解关于窗口编程的基本概念和框架。
窗口编程的世界中有四个基本概念:窗口、控件、布局、事件。使用windows(或类似)操作系统的朋友,很容易直观地理解它们。
窗口:打开一个桌面应用(比如我们使用的浏览器),一般都会以一个窗口的形式出现。
控件:所谓控件,就是显示在窗口上,用来向用户提供信息或者供用户控制窗口的组件。窗口上一般可以看到多个控件。还以浏览器为例,我们可以看到的控件是:标签页、地址输入栏、若干按钮和菜单,以及占窗口面积最大的:网页内容显示区。根据我们使用的具体浏览器与版本的不同,控件可能不完全一样。
窗口的控件,看似丰富,其实真正常用的只有十几种,包括按钮、输入框、文字、图片、复选框、单选框、下拉框、列表、菜单、标签页、进度条,等。
布局:所谓布局,就是指控件的大小和在窗口上的相对坐标。当然最准确的方法是逐一指定窗口上每个控件的大小和坐标位置。但在很多应用场景下,我们也用一些更简单快捷的方法来指定窗口的布局。
事件:如果说前面三个是窗口的静态描述,事件就是对窗口的动态描述。用户对控件的每一个有含义的操作都可以算一个事件。比如点击按钮,是一个事件;在下拉列表中进行选择,又是一个事件;在窗口上双击鼠标,当然也是事件。窗口编程的核心就是编写这些事件响应的代码。
下面我们通过一个例程,来进入窗口编程的世界。在此之前,必须安装一个第三方的python库,在我们的课程学习中,以及你自己的编程实践中,这将会是一个常见的动作。
在windows下打开命令提示符黑色窗口,粘贴这行命令并运行:
pip install pysimplegui -i https://pypi.doubanio.com/simple/
它将安装PySimpleGUI库到python当前环境中,这是一个非常好的GUI库,重点突出,屏蔽很多无须关注的细节,让我们把注意力放在编程本身。 -i 后面的部分,是为了加速。
安装必须联网,过程有几秒钟即完成,如果没有彩色的提示文字,就说明你安装正确了。
然后粘贴下面这段代码到你的编辑器中,先运行一下看看效果:
# 案例代码1:第一个窗口程序:简单的工具窗口# import 语句用法的常见改变:起别名# 效果是让代码更加简单清晰import PySimpleGUI as sgdef getNumber():# 窗口元素,这里出现了文字,输入框,按钮# 最简单的布局,仅关心行与列layout = [[sg.Text('请输入:'), sg.InputText()],[sg.Button(' 确定 '), sg.Button(' 取消 ')],]# 设置窗口的标题和窗口布局window = sg.Window('输入获取窗口', layout=layout)# 在这里,打开并等待窗口事件的触发,获取事件和窗口的输入内容event, values = window.read()# 随后关闭窗口window.close()# 默认没有输入result= None# 判断事件if event is not None and event.strip()=='确定':# None,代表空,含义是关闭窗口事件# 其它事件是按钮事件,事件名就是按钮的标题# 字符串的strip()函数,作用是过滤两端的空格# values中是窗口所有输入控件的数据a= values[0]# 字符串处理函数,判断是否纯为数字if a.isdigit():result= int(a)return resultdef simpleTest1():# 通过弹出窗口获取一个数字a= getNumber()if a is not None:print('您输入的是:', a)# 简单的遍历法查找因数(不包括1和本身),并打印for i in range(2, a):if a%i==0:print(i)else:sg.popup('您没有输入数字')# 这行语句,表示直接运行才执行后面的代码,而不是被引用(import)# 经常用于写本文件中函数的测试代码if __name__ == '__main__':simpleTest1()
运行,会首先弹出一个窗口:
当我们输入一个数字并点击“确定”按钮之后,窗口消失,屏幕上显示所输入的数字,以及它的全部因子(不包括1和自身):
这是一个控制台与窗口编程相结合的例子。
由于加了很多注释,显得代码有点长。注释中对每个涉及到的知识点进行了介绍,在正文中我们讲解一下重点内容:
引用
先看代码的最开头位置。本课程的窗口编程,必须引用PySimpleGUI这个库。import语法前面的课程简单介绍了一下,这里是一个变种版,由于这个库的名字比较长,我们通过as语句把它简化为一个简单的缩写,方便编程。
import PySimpleGUI as sg
主程序
再看代码最后的位置。
if __name__ == '__main__':simpleTest1()
当我们写一个python程序的时候,考虑到其中的功能有可能被其它python程序使用。比如这段程序就提供了一个比较实用的功能:弹出窗口获得用户输入。其它的程序有可能会用到这个功能,如果你把这个程序保存为win1.py,那么只须在其它程序的开头import win1(详见python编程基础2),并在使用的位置用类似这样的语句a=win1.getNumber()就可以了。但我们大概来不希望引入这个程序的同时它就弹出一个窗口让我们输入一个数字并对它进行因子分解!,所以,我们这个功能放在if __name__ == '__main__':的条件后面,这个判断语句的含义是:判断是正式运行还是被引入,如果是正式运行,则执行后面的语句;否则什么都不做。
测试函数
simpleTest1其实算是一个测试函数,它就是我们前面课程中讲过的通过遍历获得整数全部因子的算法(详见python编程基础3)。唯一不同的就是变量a的值,不是在代码中指定,而是通过一个函数,弹出窗口,让用户输入。所以我们重点看getNumber函数。
窗口静态描述(控件、布局、窗口)
我们这里看一下教程前面所讲的窗口相关概念在代码中是怎样落实的。看getNumber函数定义。
layout = [[sg.Text('请输入:'), sg.InputText()],[sg.Button(' 确定 '), sg.Button(' 取消 ')],]
这一段是窗口中的控件和布局。layout变量被定义成一个列表,这个列表中有两个元素,而每个元素都是一个列表,每个列表中又有两个元素。它的含义是:窗口的布局分成两行
第一行包括两个控件:一个文本显示控件,显示的内容是“请输入”;后面跟着一个输入框控件。
第二行包括两个按钮:第一个显示“确定”,第二个显示“取消”。
我们从运行的截图上也可以看到,确实是这样的。由于我们对控件的具体大小、准确位置并不关心,所以这样简单设置一下,就足够了。
再看窗口
window = sg.Window('输入获取窗口', layout=layout)
这句话,设置了窗口的标题,并把前面定义好的控件和布局,布置到这个窗口上。我们对窗口的大小也不关心,所以交给系统自己判断,能把这些控件都显示出来就好了。
窗口动态描述(事件)
看代码
event, values = window.read()window.close()
在这里,用window.read()函数打开窗口,并等待一个窗口事件。在这里,只有按钮事件。可能发生的事件有三个:关闭窗口(点击右上角的×)、点击确定按钮、点击取消按钮。一旦任何一个按下,窗口就关闭了(window.close())。
究竟发生了什么事件,保存在event变量中。如果是关闭窗口,event变量为空,在python中用(None)表示。
而在输入框控件里输入了什么内容,则保存在values变量中。values变量是一个字典,里面保存窗口所有能够输入内容的控件的值。由于我们没有为输入框控件指定特别的键值,系统就默认为0号。
其它值得注意的知识点
1、如果你仔细观察就会发现,我们为了让按钮上的文字显示得比较宽松,在两边留了空格。所以事件名不是"确定"而是" 确定 ",我们这里使用了字符串处理函数strip()来取消两边的空格。
2、用户输入的不一定是数字,如果不完全是数字,我们的转换会出错,所以我们先用另一个字符串处理函数isdigit()进行了判断,只有字符串完全由数字组成它才为真。
字符串处理函数常用的大概有二十几个,我们在课程中会逐步介绍,并在适当的时候进行总结。
3、如果你点击了取消按钮,或者直接关闭窗口,或者输入的不是一个整数,都会导致系统认为你的输入为空,于是会弹出这样的提示。
这是一个简单的格式化的窗口功能,一个无标题的窗口,上面有两个控件:文字显示和OK按钮,分两行布局。事件处理很简单:点击按钮就关闭窗口。它的作用就是提示用户某个信息,通过这样的代码来实现:
sg.popup('您没有输入数字')
更多细致的知识点内容,请仔细阅读代码中的注释。
保存这个代码,自己编程如果用到类似的功能,可以随时查阅。