### 5.4.2 案例:图形库 graphics
如前所述,Tkinter 是 Python 语言的标准库,可以利用 Tkinter 中的画布构件来绘制图形。 虽然利用 Tkinter 来进行图形编程已经比较简单、方便,但对初学者来说可能还是有点小麻 烦。例如,画布甚至都没有提供画“点”的方法,初学者希望画点时往往不知怎么办。又如, 圆形一般都是通过圆心和半径来定义的,但在画布上画圆形时必须利用界限框(外接正方形) 来定义。另外,对图形的各种操作(如移动图形、修改图形的选项值等)都是通过调用画布 的方法来执行的,而根据面向对象的思想,更容易理解的做法应该是直接针对图形对象发出 操作请求。
由于上述理由,有人①在 Tkinter 之上写了一个更容易使用的图形库——graphics。这个 图形库是为教学目的而开发的,它将 Tkinter 的绘图功能以面向对象的方式重新包装了一下, 使得初学者更容易学习和应用。使用 graphics 提供的功能实际上就是使用 Tkinter 的功能, 但使用者并不知道这一点,也不需要知道这一点,这就是层次体系结构带来的效果。图 5.23 显示了 graphics 与 Tkinter 之间的关系,其中提到的 graphics 定义的各种图形类将在稍后介 绍。
> ① Python Programming: An Introduction to Computer Science 的作者 John Zelle。
![](https://box.kancloud.cn/2016-02-22_56cafce1ed3a6.png)
图 5.23 在 Tkinter 之上开发的 graphics
graphics 模块和说明文档可以从下列网站下载:
[http://mcsp.wartburg.edu/zelle/python](http://mcsp.wartburg.edu/zelle/python)
下载后将 graphics.py 模块与你的图形程序放在一个目录中,或者放在 Python 安装目录 中即可。下面我们简要介绍如何使用 graphics 模块。
首先,需要导入 graphics 模块:
```
>>> from graphics import *
```
其次,创建一个绘图窗口:
```
>>> win = GraphWin("My Graphics Window",300,200)
```
这条语句的含义是在屏幕上创建一个窗口对象,窗口标题为"My Graphics Window",宽 度为 300 像素,高度为 200 像素。三个参数都可以省略,缺省宽度和高度都是 200 像素。窗 口的坐标系仍然是我们熟悉的,即以窗口左上角为原点,x 轴向右,y 轴向下。
通过 Graphwin 类创建绘图窗口的界面实际上是对底层 Tkinter 中创建画布对象界面的重 新包装,也就是说,当程序员利用 graphics 模块创建绘图窗口时,系统会把这个请求向下转 达给 Tkinter 模块,而 Tkinter 模块就创建一个画布对象并返回给上层的 graphics 模块。这样 做不是没事找事多此一举,而是为了改善图形编程界面的易用性、易理解性。
接下去就可以在作图窗口中绘制图形了,稍后将介绍各种图形对象的创建方法。程序结 束后应该关闭图形窗口,为此只需向窗口对象发如下消息即可:
```
>>> win.close()
```
下面介绍 graphics 模块支持的各种图形对象的用法。演示代码中总是假定已经导入了 graphics 模块并创建了绘图窗口 win。
点
graphics 模块提供了类型 Point 用于在窗口中画点。创建点对象的语句模式为:
```
>>> p = Point(<x 坐标>,<y 坐标>)
```
下面通过一个交互过程来在窗口中创建 Point 对象,并演示 Point 对象的方法的使用。
```
>>> p = Point(100,80)
>>> p.draw(win)
>>> print p.getX(),p.getY() 100 80
>>> p.move(20,30)
>>> print p.getX(),p.getY() 120 110
```
第一条语句创建了一个 Point 对象,该点的坐标为(100,80),变量 p 被赋值为该对象。
这时在窗口中并没有显示这个点,因为还需要让这个点在窗口中画出来,为此只需向对象 p 发送消息 draw(),这就是第二条语句的目的,其意为“请求对象 p 执行 draw(win)方法, 即在窗口 win 中将自己画出来”。第三条语句演示了 Point 对象的另两个方法 getX()和 getY()的使用,分别是获得点的 x 坐标和 y 坐标。第四条语句的含义是请求 Point 对象 p 改变位置,向 x 方向移动 20 像素,向 y 方向移动 30 像素。
此外,Point 对象还提供以下方法:
+ p.setFill():设置点 p 的颜色。
+ p.setOutline:设置轮廓线的颜色。对 Point 来说,与 setFill 没有区别。
+ p.undraw():隐藏对象 p,即在窗口中变成不可见的。注意,隐藏并非删除,对象 p 仍然存在,随时可以重新执行 draw()。
+ p.clone():复制。复制一个与 p 一模一样的对象。
读者一定会觉得通过 Point 类来画点非常容易,但也会奇怪:graphics 是建立在 Tkinter 之上的一层软件,graphics 的所有功能都是依赖于 Tkinter 的功能实现的,但是 Tkinter 中并未提供画点功能啊。对这个疑问的解答很简单:Point 对象其实是 Tkinter 中的一个很小的矩 形(参见图 5.23)!这是通过层次化改善图形编程界面的一个典型例子——当我们要画点时, 就直接创建 Point 对象,而不是像在 Tkinter 中那样很别扭地创建一个矩形。
接下去介绍的其他图形对象就不再像 Point 这样详细解释并演示用法了,希望使用 graphics 模块的读者可以自行练习。
直线
直线类型为 Line,创建直线对象的语句模式为:
```
>>> line = Line(<端点 1>,<端点 2>)
```
其中两个端点都是 Point 对象。
和 Point 一样,Line 对象也支持 draw()、undraw()、move()、setFill()、setOutline()、clone()等方法。此外,Line 对象还支持 setArrow()方法,用于为直线画箭头。
圆形
圆形类型为 Circle,创建圆形对象的语句模式为:
```
>>> c = Circle(<圆心>,<半径>)
```
其中圆心是 Point 对象,半径是个数值。
Circle 对象同样支持 draw()、undraw()、move()、setFill()、setOutline()、clone()等方法。此外,Circle 对象还支持 c.getRadius()方法,用于获取圆形对象 c的半径。
椭圆
椭圆类型为 Oval,创建椭圆对象的语句模式为:
```
>>> o = Oval(<左上角>,<右下角>)
```
其中左上角和右下角是两个 Point 对象,用于指定一个矩形,再由这个矩形定义一个内接椭圆。
椭圆对象同样支持 draw()、undraw()、move()、setFill()、setOutline()、 clone()等方法。
矩形
矩形类型为 Rectangle,创建矩形对象的语句模式为:
```
>>> r = Rectangle(<左上角>,<右下角>)
```
其中左上角和右下角是两个 Point 对象,用于指定矩形。
矩形对象同样支持 draw()、undraw()、move()、setFill()、setOutline()、clone() 等方法。此外,矩形还支持的方法包括 r.getP1() 、 r.getP2() 和 r.getCenter(),分别用于获取左上角、右下角和中心,返回值都是 Point 对象。
多边形
多边形类型为 Polygon,创建多边形对象的语句模式为:
```
>>> poly = Polygon(<顶点 1>,..., <顶点 n>)
```
将各顶点用直线相连,即成多边形。
矩形对象同样支持 draw()、undraw()、move()、setFill()、setOutline()、 clone()等方法。此外还支持方法 poly.getPoints(),用于获取多边形的各个顶点。
文本
文本类型为 Text,创建文本对象的语句模式为:
```
>>> t = Text(<中心点>,<字符串>)
```
其中,中心点是个 Point 对象,字符串是显示的文本内容。
文本对象支持 draw()、undraw()、move()、setFill()、setOutline()、clone()等方法,其中 setFill()和 setOutline()方法都是设置文本的颜色。文本对象还支持方法 t.setText(<新字符串>)用于改变文本内容,方法 t.getText()用于获取文本内容,方法 t.setTextColor()用于设置文本颜色。
- 前言
- 第 1 章 计算与计算思维
- 1.1 什么是计算?
- 1.1.1 计算机与计算
- 1.1.2 计算机语言
- 1.1.3 算法
- 1.1.4 实现
- 1.2 什么是计算思维?
- 1.2.1 计算思维的基本原则
- 1.2.2 计算思维的具体例子
- 1.2.3 日常生活中的计算思维
- 1.2.4 计算思维对其他学科的影响
- 1.3 初识 Python
- 1.3.1 Python 简介
- 1.3.2 第一个程序
- 1.3.3 程序的执行方式
- 1.3.4 Python 语言的基本成分
- 1.4 程序排错
- 1.5 练习
- 第 2 章 用数据表示现实世界
- 2.1 数据和数据类型
- 2.1.1 数据是对现实的抽象
- 2.1.1 常量与变量
- 2.1.2 数据类型
- 2.1.3 Python 的动态类型*
- 2.2 数值类型
- 2.2.1 整数类型 int
- 2.2.2 长整数类型 long
- 2.2.3 浮点数类型 float
- 2.2.4 数学库模块 math
- 2.2.5 复数类型 complex*
- 2.3 字符串类型 str
- 2.3.1 字符串类型的字面值形式
- 2.3.2 字符串类型的操作
- 2.3.3 字符的机内表示
- 2.3.4 字符串类型与其他类型的转换
- 2.3.5 字符串库 string
- 2.4 布尔类型 bool
- 2.4.1 关系运算
- 2.4.2 逻辑运算
- 2.4.3 布尔代数运算定律*
- 2.4.4 Python 中真假的表示与计算*
- 2.5 列表和元组类型
- 2.5.1 列表类型 list
- 2.5.2 元组类型 tuple
- 2.6 数据的输入和输出
- 2.6.1 数据的输入
- 2.6.2 数据的输出
- 2.6.3 格式化输出
- 2.7 编程案例:查找问题
- 2.8 练习
- 第 3 章 数据处理的流程控制
- 3.1 顺序控制结构
- 3.2 分支控制结构
- 3.2.1 单分支结构
- 3.2.2 两路分支结构
- 3.2.3 多路分支结构
- 3.3 异常处理
- 3.3.1 传统的错误检测方法
- 3.3.2 传统错误检测方法的缺点
- 3.3.3 异常处理机制
- 3.4 循环控制结构
- 3.4.1 for 循环
- 3.4.2 while 循环
- 3.4.3 循环的非正常中断
- 3.4.4 嵌套循环
- 3.5 结构化程序设计
- 3.5.1 程序开发过程
- 3.5.2 结构化程序设计的基本内容
- 3.6 编程案例:如何求 n 个数据的最大值?
- 3.6.1 几种解题策略
- 3.6.2 经验总结
- 3.7 Python 布尔表达式用作控制结构*
- 3.8 练习
- 第 4 章 模块化编程
- 4.1 模块化编程基本概念
- 4.1.1 模块化设计概述
- 4.1.2 模块化编程
- 4.1.3 编程语言对模块化编程的支持
- 4.2 Python 语言中的函数
- 4.2.1 用函数减少重复代码 首先看一个简单的用字符画一棵树的程序:
- 4.2.2 用函数改善程序结构
- 4.2.3 用函数增强程序的通用性
- 4.2.4 小结:函数的定义与调用
- 4.2.5 变量的作用域
- 4.2.6 函数的返回值
- 4.3 自顶向下设计
- 4.3.1 顶层设计
- 4.3.2 第二层设计
- 4.3.3 第三层设计
- 4.3.4 第四层设计
- 4.3.5 自底向上实现与单元测试
- 4.3.6 开发过程小结
- 4.4 Python 模块*
- 4.4.1 模块的创建和使用
- 4.4.2 Python 程序架构
- 4.4.3 标准库模块
- 4.4.4 模块的有条件执行
- 4.5 练习
- 第 5 章 图形编程
- 5.1 概述
- 5.1.1 计算可视化
- 5.1.2 图形是复杂数据
- 5.1.3 用对象表示复杂数据
- 5.2 Tkinter 图形编程
- 5.2.1 导入模块及创建根窗口
- 5.2.2 创建画布
- 5.2.3 在画布上绘图
- 5.2.4 图形的事件处理
- 5.3 编程案例
- 5.3.1 统计图表
- 5.3.2 计算机动画
- 5.4 软件的层次化设计:一个案例
- 5.4.1 层次化体系结构
- 5.4.2 案例:图形库 graphics
- 5.4.3 graphics 与面向对象
- 5.5 练习
- 第 6 章 大量数据的表示和处理
- 6.1 概述
- 6.2 有序的数据集合体
- 6.2.1 字符串
- 6.2.2 列表
- 6.2.3 元组
- 6.3 无序的数据集合体
- 6.3.1 集合
- 6.3.2 字典
- 6.4 文件
- 6.4.1 文件的基本概念
- 6.4.2 文件操作
- 6.4.3 编程案例:文本文件分析
- 6.4.4 缓冲
- 6.4.5 二进制文件与随机存取*
- 6.5 几种高级数据结构*
- 6.5.1 链表
- 6.5.2 堆栈
- 6.5.3 队列
- 6.6 练习
- 第 7 章 面向对象思想与编程
- 7.1 数据与操作:两种观点
- 7.1.1 面向过程观点
- 7.1.2 面向对象观点
- 7.1.3 类是类型概念的发展
- 7.2 面向对象编程
- 7.2.1 类的定义
- 7.2.2 对象的创建
- 7.2.3 对象方法的调用
- 7.2.4 编程实例:模拟炮弹飞行
- 7.2.5 类与模块化
- 7.2.6 对象的集合体
- 7.3 超类与子类*
- 7.3.1 继承
- 7.3.2 覆写
- 7.3.3 多态性
- 7.4 面向对象设计*
- 7.5 练习
- 第 8 章 图形用户界面
- 8.1 图形用户界面概述
- 8.1.1 程序的用户界面
- 8.1.2 图形界面的组成
- 8.1.3 事件驱动
- 8.2 GUI 编程
- 8.2.1 UI 编程概述
- 8.2.2 初识 Tkinter
- 8.2.3 常见 GUI 构件的用法
- 8.2.4 布局
- 8.2.5 对话框*
- 8.3 Tkinter 事件驱动编程
- 8.3.1 事件和事件对象
- 8.3.2 事件处理
- 8.4 模型-视图设计方法
- 8.4.1 将 GUI 应用程序封装成对象
- 8.4.2 模型与视图
- 8.4.3 编程案例:汇率换算器
- 8.5 练习
- 第 9 章 模拟与并发
- 9.1 模拟
- 9.1.1 计算机建模
- 9.1.2 随机问题的建模与模拟
- 9.1.3 编程案例:乒乓球比赛模拟
- 9.2 原型法
- 9.3 并行计算*
- 9.3.1 串行、并发与并行
- 9.3.2 进程与线程
- 9.3.3 多线程编程的应用
- 9.3.4 Python 多线程编程
- 9.3.5 小结
- 9.4 练习
- 第 10 章 算法设计和分析
- 10.1 枚举法
- 10.2 递归
- 10.3 分治法
- 10.4 贪心法
- 10.5 算法分析
- 10.5.1 算法复杂度
- 10.5.2 算法分析实例
- 10.6 不可计算的问题
- 10.7 练习
- 第 11 章 计算+X
- 11.1 计算数学
- 11.2 生物信息学
- 11.3 计算物理学
- 11.4 计算化学
- 11.5 计算经济学
- 11.6 练习
- 附录
- 1 Python 异常处理参考
- 2 Tkinter 画布方法
- 3 Tkinter 编程参考
- 3.1 构件属性值的设置
- 3.2 构件的标准属性
- 3.3 各种构件的属性
- 3.4 对话框
- 3.5 事件
- 参考文献