零基础python入门GUI编程:1-2 GUI编程


现在我们来看看,在面向对象的视野中,GUI编程是什么样的。

GUI编程的基本概念

  1. 组件
  2. 几何
  3. 事件

从窗口到窗口上的每一个可见的事物,都可以称作组件(widget),有时也叫做控件(control),更强调它的可控制性。

比如这个程序。窗口上有四个文本标签,一个文本输入框,和一个按钮。它们都是组件,对于面向对象编程来说,组件就是对象。这些对象的类型是系统已经设计好的,内置的类型,分别是窗口Tk,单行文本输入框Entry,标签Label,按钮Button。

组件之间的关系并不完全是平等的,比如所有的小组件都放在窗口组件内部,窗口是一个容器。对所有其他组件来说,上级就是窗口,而对于窗口来说,没有上级。

tkinter是一个相对比较简洁的GUI开发系统,类似这样的内置组件类型,只有十几个,每个都有清晰而明确的用途。我们在后面的课程中会慢慢介绍。

仅仅定义了组件的对象,以及对象的上下级关系,还不够。还必须明确这些组件的的大小、相互之间的位置关系等等。这就是几何。
tkinter采用了多种机制来进行几何布局,其中比较有特色的一种叫做grid,它的思路是把图粗略地看成一个表格,把不同的组件布置在这些表格中,比如上图。进行初步的规划后,可以把窗口分割为3*3的表格,不同的组件放在不同的格子中。

在面向对象的视野中,这种几何布局的设置,就是设置对象的属性。

设计好界面之后,我们希望按下按钮会发生一些事情。这个“按下”动作就成为事件。除了按钮事件,还有鼠标、键盘事件,等等。不同的组件会带来不同的事件。比如按钮就可以有按下事件,而文本输入框就没有这种事件。而事件所触发的事情,则通过某个对象的行为来描述(即函数)。

在面向对象的视野中,事件也是对象的属性。将组件对象的事件属性设置为某个函数,就实现了事件的功能。这种把函数与事件属性相关联的操作,有时候也叫做绑定。

回到我们当前的例子。看看这个计算按钮按下后,我们究竟应该怎么来计算华氏温度到摄氏温度的转换。
根据界面的设计,华氏温度是输入,摄氏温度是输出,我们从网上查一下,就可以找到这个公式:C=(F-32)*5/9
为了实现这个逻辑,我们把它分为三步。

  • 1、获得单行输入框的内容(访问对象的属性,函数调用语句)
  • 2、计算(按公式计算,看似简单,其实包含了很多函数调用)
  • 3、把计算结果放到恰当的标签中显示(对象属性的设置,也是一种函数调用语句)

第一个完整代码

我们看一下代码,虽然比较长,但并不复杂,每句都加了详细的注释,请认真阅读。

# 参考资料,本课程中所有的GUI程序,都必须有这一句话
from tkinter import *

# 函数定义语句,定义了计算过程
def calculate():
    # entry是上文中的单行文本输入框,从entry中取数据,用entry对象的get方法
    # get方法获得的对象是文本类型,必须转换为数字类型(float)才能用于计算
    fValue = float(entry.get())
    # 这是标准的华氏温度转摄氏温度公式
    cValue = (fValue - 32)* 5/ 9
    # 给标签的显示内容(text)属性赋值,用这种方法
    # 类似的道理,上一行的计算结果是数字,必须转换为字符串类型(str)才能用于显示
    lb1['text']= str(cValue)


# root 是主窗口
root = Tk()

# 给主窗口定一个标题
root.title("温度转换")
# entry是我们的单行文本输入框(类型Entry),它属于root窗口
entry = Entry(root)
# 它的位置第1行(row),第2列(column)
entry.grid(column=2, row=1)
# lb1是输出用的标签(类型Label),属于root窗口,一开始没有内容
lb1= Label(root)
# 它的位置第2行(row),第2列(column)
lb1.grid(column=2, row=2)

# btn是按钮(类型Button),属于root窗口,显示文字是“计算”,按下去动作(command)是函数calculate(见下)
btn= Button(root, text="计算", command=calculate)
# 它的位置第3行(row),第3列(column)
btn.grid(column=3, row=3)
# 前面这三个组件,可以说是有实际功能的组件

# lb2是输出用的标签(类型Label),属于root窗口,内容为华氏度标记℉
lb2= Label(root, text="°F")
# 它的位置第1行(row),第3列(column)
lb2.grid(column=3, row=1)

# lb3是输出用的标签(类型Label),属于root窗口,内容为一个说明性的信息
lb3= Label(root, text="等于摄氏")
# 它的位置第2行(row),第1列(column)
lb3.grid(column=1, row=2)

# lb2是输出用的标签(类型Label),属于root窗口,内容为摄氏度标记℃
lb4= Label(root, text="°C")
# 它的位置第2行(row),第3列(column)
lb4.grid(column=3, row=2)
# 后面这三个组件,没有实际的功能,作用就是给使用者一些提示和说明
# 前面三个组件如果缺少任何一个,程序都不能正常运行了
# 后面三个组件如果没有,能够正常运行,但用起来会感觉莫名其妙

# 这一句是运行窗口
root.mainloop()

函数calculate,它的作用是计算计算华氏度转摄氏度。函数定义的开始,是函数定义语句;函数定义的结束,是缩进的结束。

前面说过导入语句(from ... import ...)的作用是“参考资料”,如果有哪个术语你搞不清楚是什么意思,那么就去看这个文件中的定义。而函数定义语句与它类似,函数是在本文中进行的“术语定义”,不属于正文内容。
它们的含义是:
当我说calculate的时候,我的意思是...

从root = Tk()开始是故事的正文。我们发现它与上节课的最简窗口代码相比,多了十三条语句,都是函数调用语句。
设置窗口标题一行语句,后面两行为一组,一共十二行,创建并布局了六个组件。

如果把写程序比喻为写文章,这篇文章的故事是这样的:

参考资料:《Tkinter》
术语定义:当我说calculate(计算)的时候,我的意思是...
有一个窗口叫root。
它的标题是:温度转换
窗口上有六个组件,它们的定义和布置分别是...
显示root窗口。

定义的calculate(计算)函数在哪里执行呢?程序中做了说明:当按钮按下时,才执行。

小结

我们看了一个具备了初步功能的、比较完整的GUI程序,对GUI程序的三个基本概念有了一定程度的感性认识。
组件:窗口,三个实际功能组件,三个纯提示说明组件
几何:(除了窗口之外)每个组件的布局方法
事件:按钮事件

我们也接触到了python六种语句中的三种:导入语句、函数定义语句、函数调用语句。
其中函数调用语句是出现最多的,变化形式也是最多的:有调用对象的函数,有调用自己定义的函数,有些看起来甚至不像是调用函数(比如给对象的属性赋值)但实际上这些都是调用函数:除了导入语句,所有不以冒号结尾的语句,都是函数调用语句。

本节作业

1、修改代码,改变显示文字和计算逻辑,把它改成另外一种单位转换工具。
可以是复杂一点的《面积转换》,把亩换算成平方米。也可以是简单一点的《长度转换》,把米换算成厘米。
2、凡是#开头的代码,都是注释,不属于正常的python语句。
随意注释掉某行代码,看看程序是否能够运行,如果不能运行,有什么样的提示出现。
3、函数定义语句后面本函数的代码必须有统一的缩进。
尝试在某行前面加一个空格或删除一个空格,运行程序,看看有什么样的提示出现。

猜你喜欢

转载自blog.csdn.net/xiaorang/article/details/105610454