程序设计思想与方法 (5a) 图形界面编程

55
1 程程程程程程程程程 (5a) 图图图图图图 图 图 图图图图图图图图图 图图图图图图 zhaohai @cs.sjtu.edu.cn

Upload: desiree-simpson

Post on 31-Dec-2015

112 views

Category:

Documents


7 download

DESCRIPTION

程序设计思想与方法 (5a) 图形界面编程. 赵 海 计算机科学与工程系 上海交通大学 zhaohai @cs.sjtu.edu.cn. 学习目标. 理解对象的概念,以及它如何能用于简化编程。 熟悉图形库 ( 模块 ) 中的各种对象。 能在编程中创建对象并调用合适的方法完成图形计算。. 学习目标. 理解计算机图形学的基础概念,特别是坐标系统和坐标变换 。 在图形编程中,理解如何使用鼠标和文本输入。 能够用图形库编写简单的交互图形程序。. 概要. 每种数据类型能代表一组值,并且具备一组关联的操作运算。 传统的编程观点认为,数据是被动的,它由主动的操作运算来控制。. - PowerPoint PPT Presentation

TRANSCRIPT

Page 1: 程序设计思想与方法  (5a) 图形界面编程

1

程序设计思想与方法 (5a)

图形界面编程赵 海

计算机科学与工程系上海交通大学

[email protected]

Page 2: 程序设计思想与方法  (5a) 图形界面编程

2

学习目标• 理解对象的概念,以及它如何能用于简化

编程。• 熟悉图形库 ( 模块 ) 中的各种对象。• 能在编程中创建对象并调用合适的方法完

成图形计算。

Page 3: 程序设计思想与方法  (5a) 图形界面编程

3

学习目标• 理解计算机图形学的基础概念,特别是坐

标系统和坐标变换 。• 在图形编程中,理解如何使用鼠标和文本

输入。• 能够用图形库编写简单的交互图形程序。

Page 4: 程序设计思想与方法  (5a) 图形界面编程

4

概要• 每种数据类型能代表一组值,并且具备一

组关联的操作运算。• 传统的编程观点认为,数据是被动的,它

由主动的操作运算来控制。

Page 5: 程序设计思想与方法  (5a) 图形界面编程

5

概要• 现代计算机程序使用面向对象的 (object-oriented)

方法来构建。• 你熟悉的应用程序都具有图形用户界面 ( 接口 ) (

Graphical User Interfaces , GUI ),提供视窗、图标、按钮和菜单等元素。

• 本教材专门提供一个图形库 (graphics.py) ,它基于 Tkinter 书写 .

Page 6: 程序设计思想与方法  (5a) 图形界面编程

6

对象 (objects) 的目的、作用• 基本思路 – 视一个复杂系统为一些简单对

象的交互。一个对象是一类活跃的数据类型,它结合了数据和上面的操作。

• 对象知道一些事情 ( 包含数据 ) ,并且,它能做一些事情 ( 具备操作 ).

• [ 图形 ] 对象之间的交互通过彼此发送消息( messages )来实现。

Page 7: 程序设计思想与方法  (5a) 图形界面编程

7

对象 (objects) 的目的• 假定我们要给一个大学开发一个数据处理

系统。• 我们需要维护入学的学生的纪录。每个学

生可以表示为一个对象。

Page 8: 程序设计思想与方法  (5a) 图形界面编程

8

对象 (objects) 的目的• 学生对象将包含如下数据 :

– 姓名– 学生证号– 选修的课程– 宿舍地址– 家庭地址– GPA– 等等 .

Page 9: 程序设计思想与方法  (5a) 图形界面编程

9

对象 (objects) 的目的• 学生对象应能对处理请求作出相应。• 我们可能想发出一个全校范围的邮件,因此,我

们需要每个学生的宿舍地址。• 我们能发送 printCampusAddress 消息给每

个学生对象。 当学生对象接到这个消息后,它能打印自己的地址。

Page 10: 程序设计思想与方法  (5a) 图形界面编程

10

对象 (objects) 的目的• 对象可以引用其它对象。• 每个课程可以表示为一个对象 :

– 授课教师– 学生名单– 先修课程– 上课时间和地点

Page 11: 程序设计思想与方法  (5a) 图形界面编程

11

对象 (objects) 的目的• 操作示例

– addStudent– delStudent– changeRoom–等等

Page 12: 程序设计思想与方法  (5a) 图形界面编程

12

简单的图形编程• 使用图形库 graphics.py 。• 图形库的位置:

– Python 的库目录(文件夹),和其它库文件在一起。

– 和你的图形程序在同一目录。

Page 13: 程序设计思想与方法  (5a) 图形界面编程

13

简单的图形编程• 我们首先需要按照模块导入这个库>>> import graphics

• 一个图形窗口是一个屏幕区域,所要展现的图形将出现其中。>>> win = graphics.GraphWin()

• 该命令生成一个新的窗口,题为 “ Graphics Window.”

Page 14: 程序设计思想与方法  (5a) 图形界面编程

14

简单的图形编程• GraphWin 是一个分配给变量 win 的对象。

我们能通过这个变量来操作这个对象,类似于通过文件句柄来操作文件。

• 窗口能被如下的命令关闭或者销毁 >>> win.close()

Page 15: 程序设计思想与方法  (5a) 图形界面编程

15

简单的图形界面编程

Page 16: 程序设计思想与方法  (5a) 图形界面编程

16

简单的图形界面编程• 每次调用图形库中的函数都要使用标识graphics. 是一件很麻烦的事

• from graphics import *“from” 命令允许你从模块库中加载相应的函数。 “ *” 是加载所有函数;或者你也可以选择加载自己指定的函数 .

Page 17: 程序设计思想与方法  (5a) 图形界面编程

17

简单的图形界面编程• 像这样使用 import 命令可以消除在调用图形库函

数之前一定要添加的前缀标识 graphics.>>> from graphics import *>>> win = GraphWin()

Page 18: 程序设计思想与方法  (5a) 图形界面编程

18

简单的图形界面编程• 一个图形界面窗口是由像素点组成的 ,像素是图

形的基本组成要素。• 默认的 GraphWin 是 200 像素高, 200 像素宽

( 一共 40,000).• 一个在窗口中绘制图形的方法就是一次画一个像

素点。但是这太麻烦了,图形库有很多事先定义好的函数可以直接绘制几何图形。

Page 19: 程序设计思想与方法  (5a) 图形界面编程

19

简单的图形界面编程• 最简单的对象是 Point 。与几何中的点的表示一

样 , 点的坐标由坐标系统 (x, y) 表示 , 其中 x 是横坐标, y 是纵坐标 .

• 图形窗口中的原点 (0,0) 在窗口的左上角 .• X 的值从左往右增大 , y 的值从上往下增大 .• 右下角的坐标是 (199, 199)

Page 20: 程序设计思想与方法  (5a) 图形界面编程

20

简单的图形界面编程>>> p = Point(50, 60)

>>> p.getX()

50

>>> p.getY()

60

>>> win = GraphWin()

>>> p.draw(win)

>>> p2 = Point(140, 100)

>>> p2.draw(win)

Page 21: 程序设计思想与方法  (5a) 图形界面编程

21

简单的图形界面编程>>> ### 打开一个图形窗口>>> win = GraphWin('Shapes')>>> ### 绘制一个圆点在 (100, 100)半径是 30 的红色的圆>>> center = Point(100, 100)>>> circ = Circle(center, 30)>>> circ.setFill('red')>>> circ.draw(win)>>> ### 在圆的中心绘制一个文字标签>>> label = Text(center, "Red Circle")>>> label.draw(win)>>> ### 使用 Rectangle 对象绘制一个正方形>>> rect = Rectangle(Point(30, 30), Point(70, 70))>>> rect.draw(win)>>> ### 使用 Line 对象绘制一条线段>>> line = Line(Point(20, 30), Point(180, 165))>>> line.draw(win)>>> ### 使用 Oval绘制一个椭圆>>> oval = Oval(Point(20, 150), Point(180, 199))>>> oval.draw(win)

Page 22: 程序设计思想与方法  (5a) 图形界面编程

22

使用图形对象• 系统通过让对象执行它相应的函数来实现

相应的功能 .

• 在前一个例子中,我们使用了 GraphWin, Point, Circle, Oval, Line, Text 以及 Rectangle. 它们向我们展示了这些类是如何使用的 .

Page 23: 程序设计思想与方法  (5a) 图形界面编程

23

使用图形对象• 每一个对象都是一个类的实例,这个类描述了这个实例的特性。

• 如果我们说 Augie 是一条狗 , 我们实际上是在说 Augie 狗这个大类中的一个特定的个体 . Augie 是狗这个类的一个实例。

Page 24: 程序设计思想与方法  (5a) 图形界面编程

24

使用图形对象• 我们使用一个特定的操作称为构造函数

(constructor) 来新创建一个类的实例 .<class-name>(<param1>, <param2>, …)

• <class-name> 是我们想要构建的实例的类的名字 , 例如 . Circle 或者 Point.

• 参数是用来初始化这个对象用的。例如: Point 需要两个数字参数

Page 25: 程序设计思想与方法  (5a) 图形界面编程

25

使用图形对象• p = Point(50, 60)

Point 类的构造函数需要两个参数,点的 x与 y 坐标 .

• 这些值会作为实例变量存储在对象中 .

Page 26: 程序设计思想与方法  (5a) 图形界面编程

26

使用图形对象• 这里只展示了最相关的实例变量(其它的还包括颜色,父窗口等等暂时隐藏)

Page 27: 程序设计思想与方法  (5a) 图形界面编程

27

使用图形对象• 要让对象执行操作,我们需要给对象传递一个信

息,而一个对象可以响应的所有的信息集合称作这个对象的方法 (Method) .

• 方法就好比对象内部的函数• 你可以通过“点”来调用方法 :

<object>.<method-name>(<param1>, <param2>, …)

Page 28: 程序设计思想与方法  (5a) 图形界面编程

28

使用图形对象• p.getX() 与 p.getY() 返回一个点的 x与y 的值 . 像这种常规方法被称为访问方法(accessors) ,因为它们可以获取对象中的实例变量信息 .

Page 29: 程序设计思想与方法  (5a) 图形界面编程

29

使用图形对象• 其它的方法通过改变对象的实例变量的值来改变

对象的状态 .• move(dx, dy) 把对象在 x 方向上移动 dx 个单位在 y

方向上移动 dy 个单位 .• Move 操作擦除了老的图像,然后在新位置上绘制

一个新图像 . 像这种改变对象状态的方法称为修改方法 (mutators).

Page 30: 程序设计思想与方法  (5a) 图形界面编程

30

使用图形对象>>> circ = Circle(Point(100, 100), 30)>>> win = GraphWin()>>> circ.draw(win)

• 第一行创建了一个半径 30 ,圆点在 (100,100) 的圆 .

• 我们使用 Point 构造函数为这个圆的中心创建了一个点 .

• 最后一行是 Circle 对象 circ 在 GraphWin 对象win 中绘制它自己 .

Page 31: 程序设计思想与方法  (5a) 图形界面编程

31

使用图形对象• draw 方法会使用实例

变量,获取圆点、半径信息 .

Page 32: 程序设计思想与方法  (5a) 图形界面编程

32

使用图形对象• 两个不同的变量指向同一个对象是可以的——这

时对其中一个变量的修改会直接同步影响到另一个变量>>> leftEye = Circle(Point(80,50), 5)>>> leftEye.setFill('yellow')>>> leftEye.setOutline('red')>>> rightEye = leftEye>>> rightEye.move(20,0)

• 这段代码的想法是首先创建一个左眼对象,然后把它拷贝给右眼对象,然后移动右眼对象 20 个单位 ( 相当于画两只眼睛,可惜它没有成功 ).

Page 33: 程序设计思想与方法  (5a) 图形界面编程

33

使用图形对象• 赋值语句 rightEye = leftEye 让左眼与右眼都指向了同一个 circle 对象!

• 像这种两个变量都指向同一个对象的情形,成为别名 (aliasing).

Page 34: 程序设计思想与方法  (5a) 图形界面编程

34

使用图形对象

Page 35: 程序设计思想与方法  (5a) 图形界面编程

35

使用图形对象• 有两种方法可以解决这个别名问题 .• 我们可以绘制两个圆 circles, 给两个眼睛分

别画一个 :>>> leftEye = Circle(Point(80, 50), 5)>>> leftEye.setFill('yellow')>>> leftEye.setOutline('red')>>> rightEye = Circle(Point(100, 50), 5)>>> rightEye.setFill('yellow')>>> rightEye.setOutline('red')

Page 36: 程序设计思想与方法  (5a) 图形界面编程

36

使用图形对象• 图形库里有个更好的解决办法 . 图形对象

有一个拷贝方法 (clone) ,可以拷贝该对象>>> # Correct way to create two circles, using clone>>> leftEye = Circle(Point(80, 50), 5)>>> leftEye.setFill('yellow')>>> leftEye.setOutline('red')>>> rightEye = leftEye.clone() # rightEye is an exact copy of the left>>> rightEye.move(20, 0)

Page 37: 程序设计思想与方法  (5a) 图形界面编程

37

数据绘制 /选择坐标

win = GraphWin("Investment Growth Chart", 320, 240)

win.setCoords(-1.75,-200, 11.5, 10400)

Page 38: 程序设计思想与方法  (5a) 图形界面编程

38

可交互的图形界面• 在图形界面环境中,用户通常通过点击按

钮、选择菜单选项、在输入框中输入文字来实现与程序的交互 .

• 事件驱动 (Event-driven) 程序在屏幕上绘制交互元素 (小插件 /widgets) ,然后等待用户操作 .

Page 39: 程序设计思想与方法  (5a) 图形界面编程

39

可交互的图形界面• 当用户移动鼠标、点击鼠标或者敲打键盘

是,一个事件 (event)就产生了 .• 事件是一个对象,它封装了刚刚发生的事

件的信息• 事件对象会被送给程序的相应部分进行处

理,比如按钮事件 (button event).

Page 40: 程序设计思想与方法  (5a) 图形界面编程

40

可交互的图形界面• 图形操作模块隐藏了底层的窗口操作管理,只在 GraphWin 中提供了两个简单的方法来获取用户输入 .

Page 41: 程序设计思想与方法  (5a) 图形界面编程

41

获取鼠标点击• 我们可以通过调用 GraphWin 类中的 getMouse

方法来获取图形信息 .• 当 GraphWin 中的 getMouse 被调用时 , 程序暂停运行,然后等待用户在窗口中的某处点击鼠标 .

• 用户点击的地方的信息会封装成 Point返回 .

Page 42: 程序设计思想与方法  (5a) 图形界面编程

42

获取鼠标点击• 这段代码可以打印鼠标点击的坐标 :

from graphics import *win = GraphWin("Click Me!")p = win.getMouse()print "You clicked (%d, %d)" % (p.getX(), p.getY())

• 对于返回的 point 的操作,我们可以使用访问方法例如 getX 以及 getY 或者其他的方法 .

Page 43: 程序设计思想与方法  (5a) 图形界面编程

43

获取鼠标点击# triangle.pyw# 用可交互的图形编程来画一个三角形

from graphics import *

def main(): win = GraphWin("画一个三角形 ") win.setCoords(0.0, 0.0, 10.0, 10.0) message = Text(Point(5, 0.5), " 请点三个点 ") message.draw(win)

# 获取并绘制三角形的三个顶点 p1 = win.getMouse() p1.draw(win) p2 = win.getMouse() p2.draw(win) p3 = win.getMouse() p3.draw(win)

Page 44: 程序设计思想与方法  (5a) 图形界面编程

44

获取鼠标点击# 使用多边形对象来绘制三角形 triangle = Polygon(p1,p2,p3)

triangle.setFill("peachpuff")

triangle.setOutline("cyan")

triangle.draw(win)

# 等待再一次点击推出程序 message.setText("随便点击推出程序 .")

win.getMouse()

main()

Page 45: 程序设计思想与方法  (5a) 图形界面编程

45

获取鼠标点击

Page 46: 程序设计思想与方法  (5a) 图形界面编程

46

获取鼠标点击• 注意 :

– 当你在 windows环境下编程时 , 如果你使用 .pyw 后缀,双击运行你的 python 程序时, Python 的 shell 窗口不会显示出来 .

– 没有三角形类,所以我使用了更一般的多边形类,这个类可以把任意多的点连接成一个封闭图形 .

Page 47: 程序设计思想与方法  (5a) 图形界面编程

47

获取鼠标点击– 一旦你获取了三个点 , 创建一个三角形就很容易了 :

triangle = Polygon(p1, p2, p3)

– 在程序的开始处创建并绘制一个文本对象 .message = Text(Point(5,0.5), “Click on three points”)message.draw(win)

– 要改变提示,只要修改要展示的文字即可message.setText(“Click anywhere to quit.”)

Page 48: 程序设计思想与方法  (5a) 图形界面编程

48

处理文字输入• 这个三角形程序的输入完全靠鼠标点击 . 这里还

有一个 Entry 对象可以获取键盘输入 .• Entry 对象能在屏幕上绘制一个文本框,可以包

含文本 . 这个对象同样也有 setText 与 getText 方法,不过它还能编辑输入 .

Page 49: 程序设计思想与方法  (5a) 图形界面编程

49

处理文字输入

Page 50: 程序设计思想与方法  (5a) 图形界面编程

50

处理文字输入# convert_gui.pyw# 使用简单的图形界面# 实现的摄氏度转华氏度的程序 .

from graphics import *

def main(): win = GraphWin("Celsius Converter", 300, 200) win.setCoords(0.0, 0.0, 3.0, 4.0) # 绘制界面 Text(Point(1,3), " Celsius Temperature:").draw(win) Text(Point(1,1), "Fahrenheit Temperature:").draw(win) input = Entry(Point(2,3), 5) input.setText("0.0") input.draw(win) output = Text(Point(2,1),"") output.draw(win) button = Text(Point(1.5,2.0),"Convert It") button.draw(win) Rectangle(Point(1,1.5), Point(2,2.5)).draw(win)

Page 51: 程序设计思想与方法  (5a) 图形界面编程

51

处理文字输入 # 等待一次鼠标点击 win.getMouse()

# 转换输入 celsius = eval(input.getText()) fahrenheit = 9.0/5.0 * celsius + 32

# 展示输出并且改变按钮 output.setText("%0.1f" % fahrenheit) button.setText("Quit")

# 等待点击并推出 win.getMouse() win.close() main()

Page 52: 程序设计思想与方法  (5a) 图形界面编程

52

处理文字输入

Page 53: 程序设计思想与方法  (5a) 图形界面编程

53

处理文字输入• 运行时,这个程序会绘制一个带有输入框

的窗口,以供用户输入摄氏度,还带有一个按钮来进行转换 .– 这个按钮当前还没有用,只是个摆设!我们现

在只是等待任意一次鼠标点击 .

Page 54: 程序设计思想与方法  (5a) 图形界面编程

54

处理文字输入• 初始时 , 我们设置输入框包含内容 “ 0.0”.

• 用户可以删掉这个值然后另外输一个值 .

• 当用户点击鼠标时,程序就会停止结束——由于我们也不关心在哪儿点的鼠标,所以我们不会存储点的位置 !

Page 55: 程序设计思想与方法  (5a) 图形界面编程

55

处理文字输入• 对输入处理分为三个步骤 :

– 输入的值会被 eval函数转换成数字 .– 这个数字会被转为华氏温度 .–然后这个数字会被转成字符串然后转成要输出

的格式,在 output字符区域中输出 .