Tkinter库的学习记录19-Canvas
19、Canvas本章将介绍tkinter模块内Canvas这个模块可以绘图也可以制作动画而动画也是设计游戏的基础本章将完整介绍这方面的知识。19-1 绘图功能19-1-1 建立画布可以使用Canvas()方法建立画布对象。tk Tk() # 使用tk当窗口Tk对象 canvas Canvas(tk, widthxx, heightyy) # xxyy是画布的宽与高 canvas.pack() # 可以将画布包装好这是必要的画布建立完成后左上角是坐标(0, 0)向右x轴递增向下y轴递增。19-1-2 绘制线条create_line()它的使用方式如下。create_line(x1, y1, x2, y2, ..., xn, yn, option)线条将会沿着(x1, y1), (x2, y2), ...绘制下去下列是常用的options用法。(1) arrow默认是没有箭头使用arrowtk.FIRST在起始线末端有箭头arrowLAST在最后一条线末端有箭头使用arrowtk.BOTH在两端有箭头。(2) arrowshape使用元组(d1, d2, d3)代表箭头默认是(8, 10, 3)。(3) capstyle这是线条终点的样式默认是BUTT也可以选择PROJECTINGROUND程序实例可以参考ch19_4。(4) dash建立虚线使用元组储存数字数据第一个数字是实线第二个数字是空白如此循环当所有元组数字用完又重新开始。例如dash(5, 3)产生5像素实现3像素空白如此循环。再如dash(8, 1, 1, 1)产生8像素实线和点的线条dash(5, )产生5像素实线5像素空白。(5) dashoffset与dash一样产生虚线但是一开始数字是空白的宽度。(6) fill设置线条颜色。(7) joinstyle线条相交的设置默认是ROUND也可以选择BEVEL、MITER程序实例可以参考ch19_3。(8) stipple绘制位图(Bitmap)线条可以参考2-8节程序实例可以参考ch19_5。(9) width线条宽度。程序实例ch19_1在半径为100的圆外围建立12个点然后将这些点彼此连接。from tkinter import * import math tk Tk() canvas Canvas(tk, width640, height480) canvas.pack() x_center, y_center, r 320, 240, 100 x, y [], [] for i in range(12): # 建立圆外围12个点 x.append(x_center r * math.cos(30*i*math.pi/180)) y.append(y_center r * math.sin(30*i*math.pi/180)) for i in range(12): # 画出12条线段 for j in range(12): canvas.create_line(x[i], y[i], x[j], y[j]) tk.mainloop()执行结果上述程序使用了数学函数sin()和cos()以及pi这些是在math模块。使用create_line()时在options参数字段可以用fill设置线条颜色用width设置线条宽度。程序实例ch19_2用不同线条颜色与宽度。from tkinter import * tk Tk() canvas Canvas(tk, width640, height480) canvas.pack() canvas.create_line(100, 100, 500, 100) canvas.create_line(100, 125, 500, 125, width5) canvas.create_line(100, 150, 500, 150, width10, fillblue) canvas.create_line(100, 175, 500, 175, dash(10, 2, 2, 2)) tk.mainloop()执行结果程序实例ch19_3由线条交接了解joinstyle参数的应用。# ch19_.py from tkinter import * import math tk Tk() canvas Canvas(tk, width640, height480) canvas.pack() canvas.create_line(30, 30, 500, 30, 265, 100, 30, 30, width20, joinstyleROUND) canvas.create_line(30, 130, 500, 130, 265, 200, 30, 130, width20, joinstyleBEVEL) canvas.create_line(30, 230, 500, 230, 265, 300, 30, 230, width20, joinstyleMITER) tk.mainloop()执行结果程序实例ch19_4由线条了解capstyle参数的应用。# ch19_.py from tkinter import * import math tk Tk() canvas Canvas(tk, width640, height480) canvas.pack() canvas.create_line(30, 30, 500, 30, width10, capstyleBUTT) canvas.create_line(30, 130, 500, 130, width10, capstyleROUND) canvas.create_line(30, 230, 500, 230, width10, capstylePROJECTING) # 以下垂直线 canvas.create_line(30, 20, 30, 240) canvas.create_line(500, 20, 500, 250) tk.mainloop()执行结果程序实例ch19_5建立位图线条。# ch19_.py from tkinter import * import math tk Tk() canvas Canvas(tk, width640, height480) canvas.pack() canvas.create_line(30, 30, 500, 30, width10, stipplegray25) canvas.create_line(30, 130, 500, 130, width40, stipplequesthead) canvas.create_line(30, 230, 500, 230, width10, stippleinfo) tk.mainloop()执行结果19-1-3 绘制矩形createrec_tangle()它的使用方式如下。create_rectangle(x1, y1, x2, y2, option)(x1, y1)和(x2, y2)是矩形左上角和右下角的坐标下列是·常用的options用法。(1) dash建立虚线与create_lin()相同。(2) dasgoffset与fash一样产生虚线但是一开始数字是空白的宽度。(3) fill矩形填充颜色。(4) outline设置矩形线条颜色。(5) stipple绘制位图矩形可以参考2-8节程序实例可以参考ch19_5。(6) width矩形线条宽度。程序实例ch19_6在画布内随机产生不同位置与大小的矩形。# ch19_.py from tkinter import * from random import * tk Tk() canvas Canvas(tk, width640, height480) canvas.pack() for i in range(50): # 随机绘制50个不同位置与大小的矩形 x1, y1 randint(1, 640), randint(1, 480) x2, y2 randint(1, 640), randint(1, 480) if x1 x2 : x1, x2 x2, x1 # 确保左上角x坐标小于右下角x坐标 if y1 y2 : y1, y2 y2, y1 # 确保左上角y坐标小于右下角y坐标 canvas.create_rectangle(x1, y1, x2, y2) tk.mainloop()执行结果这个程序每次执行时都会产生不同的结果有一点儿艺术画的效果。使用create_rectangle()时在options参数字段可以用fill‘color’设置矩形填充颜色用outlinecolor设置矩形轮廓颜色。程序实例ch19_7绘制三个矩形第一个使用红色填充轮廓是默认设置第二个使用黄色填充轮廓是蓝色。第三个使用绿色填充轮廓是灰色。from tkinter import * tk Tk() canvas Canvas(tk, width640, height480) canvas.pack() canvas.create_rectangle(10, 10, 120, 60, fillred) canvas.create_rectangle(130, 10, 200, 80, fillyellow) canvas.create_rectangle(210, 10, 300, 60, fillgreen) tk.mainloop()执行结果由执行结果可以发现由于画布底色是浅灰色所以第三个矩形用灰色轮廓几乎看不到轮廓线另外也可以用width设置矩形轮廓的宽度。19-1-4 绘制圆弧create_arc()它的使用方式如下。create_arc(x1, y1, x2, y2, extentangle, styleARC, options)(x1, y1)和(x2, y2)分别是圆弧左上角和右下角的坐标下列是常用的options用法。(1) dash建立虚线与create_line()相同。(2) dashoffset与dash一样产生虚线但是一开始数字是空白的宽度。(3) extent如果是绘制圆形extent值是359如果写成360会使为0°。如果extent介于1 ~ 359则是绘制这个角度的圆弧。(4) fill填充圆弧颜色。(5) outline设置圆弧线条颜色。(6) start圆弧起点位置。(7) stipple绘制位图圆弧。(8) style有三种格式——ARC、CHORD、PIESLICE可参考ch19_9。(9) width圆弧线条宽度。上述styleARC表示绘制圆弧如果是要使用options参数填满圆弧则须舍去此参数。此外options参数可以使用width设置轮廓线条宽度(可参考下列ch19_8第12行)outline设置轮廓线条颜色(可参考下列ch19_8的第15行)fill设置填充颜色(可参考下列ch19_8第10行)。目前默认绘制圆弧的起点是右边也可以用start0代表。也可以设置start的值更改圆弧的起点方向是逆时针可参考ch19_8第13行。程序实例ch19_8绘制各种不同的圆和椭圆以及圆弧和椭圆弧。from tkinter import * tk Tk() canvas Canvas(tk, width640, height480) canvas.pack() # 以下以圆形为基础 canvas.create_arc(10, 10, 110, 110, extent45, styleARC) canvas.create_arc(210, 10, 310, 110, extent90, styleARC) canvas.create_arc(410, 10, 510, 110, extent180, fillyellow) canvas.create_arc(10, 110, 110, 210, extent270, styleARC) canvas.create_arc(210, 110, 310, 210, extent255, styleARC, width5) # 以下以椭圆形为基础 canvas.create_arc(10, 250, 310, 350, extent90, styleARC, start90) canvas.create_arc(320, 250, 620, 350, extent180, styleARC) canvas.create_arc(10, 360, 310, 460, extent270, styleARC, outlineblue) canvas.create_arc(320, 360, 620, 460, extent359, styleARC) tk.mainloop()执行结果程序实例ch19_9style参数分别是ARC、CHORD、PIESLICE的应用。from tkinter import * tk Tk() canvas Canvas(tk, width640, height480) canvas.pack() # 以下以圆形为基础 canvas.create_arc(10, 10, 110, 110, extent180, styleARC) canvas.create_arc(210, 10, 310, 110, extent180, styleCHORD) canvas.create_arc(410, 10, 510, 110, start30, extent120, stylePIESLICE) tk.mainloop()执行结果19-1-5 绘制圆或椭圆create_oval()它的使用方式如下。create_oval(x1, y1, x2, y2, options)(x1, y1)和(x2, y2)分别是圆或椭圆的左上角和右下角坐标下列是常用的options用法。(1) dash建立虚线与create_line()相同。(2) dashoffset与dash一样产生虚线但是一开始数字是空白的宽度。(3) fill设置圆或椭圆的填充颜色。(4) outline设置圆或椭圆边界颜色。(5) stipple绘制位图边界的圆或椭圆。(6) width圆或椭圆线条宽度。程序实例ch19_10圆和椭圆的绘制。from tkinter import * tk Tk() canvas Canvas(tk, width640, height480) canvas.pack() # 以下以圆形 canvas.create_oval(10, 10, 110, 110) canvas.create_oval(150, 10, 300, 160, fillyellow) # 以下是椭圆形 canvas.create_oval(10, 200, 310, 350) canvas.create_oval(350, 200, 550, 300, fillaqua, outlineblue, width5) tk.mainloop()执行结果19-1-6 绘制多边形create_polygon()它的使用方式如下。create_polygon(x1, y1, x2, y2, x3, y3, ..., xn, yn, options)(x1, y1) ...,(xn, yn)是多边形割胶的(x, y)坐标下列是常用的options用法。(1) dash建立虚线与create_line()相同。(2) dashoffset与dash一样产生虚线但是一开始数字是空白的宽度。(3) fill设置多边形的填充颜色。(4) outline设置多边形边界颜色。(5) stipple绘制位图边界的多边形。(6) width多边形线条宽度。程序实例ch19_11绘制多边形的应用。from tkinter import * tk Tk() canvas Canvas(tk, width640, height480) canvas.pack() canvas.create_polygon(10, 10, 100, 10, 50, 80, fill, outlineblack) canvas.create_polygon(120, 10, 180, 30, 250, 100, 200, 90, 130, 80) canvas.create_polygon(200, 10, 350, 30, 420, 70, 360, 90, fillaqua) canvas.create_polygon(400, 10, 600, 10, 450, 80, width5, outlineblue, fillyellow) tk.mainloop()执行结果19-1-7 输出文字create_text()它的使用方式如下。create_text(x, y, textxxx, options)默认(x, y)是文字字符串输出的中心坐标下列是常用的options用法。(1) anchor默认是anchorCENTER也可以参考2-4节的位置概念。(2) fill文字颜色。(3) font字形的使用可以参考2-6节。(4) justify当输出多行时默认是靠左LEFT更多概念可以参考2-7节。(5) stipple绘制位图线条的文字默认是”“表示实线。(6) text输出的文字。(8) width多边形线条宽度。程序实例ch19_12输出文字的应用。from tkinter import * tk Tk() canvas Canvas(tk, width640, height480) canvas.pack() canvas.create_text(200, 50, textHello world!) canvas.create_text(200, 80, textHello python!, fillblue) canvas.create_text(300, 120, textHello tkinter!, fillblue, font(Times New Roman, 20)) tk.mainloop()执行结果19-1-8 更改画布背景颜色在使用Canvas()方法建立画布时可以加上bg参数设置画布背景颜色。程序实例ch19_13将画布背景改成黄色。from tkinter import * tk Tk() canvas Canvas(tk, width640, height480, bgyellow) canvas.pack() tk.mainloop()执行结果19-1-9 插入图像create_image()在Canvas控件内可以使用create_image()在Canvas对象内插入图像文件它的语法如下。create_image(x, y, options)(x, y)是图像左上角的位置下列是常用的options用法。(1) anchor默认是anchorCENTER也可以参考2-4节的位置概念。(2)image插入的图像。下面将以实例讲解。程序实例ch19_14插入图像文件这个程序会建立窗口x轴大于图像宽度30像素y轴大于图像高度20像素。from tkinter import * from PIL import Image, ImageTk tk Tk() img Image.open(sun.jpg) sunMore ImageTk.PhotoImage(img) canvas Canvas(tk, widthimg.size[0]40, heightimg.size[1]30) canvas.create_image(20, 15, anchorNW, imagesunMore) canvas.pack(fillBOTH, expandTrue) tk.mainloop()执行结果19-2 鼠标拖曳绘制线条Python的tkinter模块在Canvas控件部分并没有提供绘制点的工具不过我们可以使用鼠标拖曳时绑定paint事件处理程序在这个事件中可以取得鼠标坐标然后使用create_oval()方法绘制极小化的圆方法是圆的左上角坐标与右下角坐标相同可以参考下列实例。程序实例ch19_15设计一个简单的绘图程序这个程序在执行时若是拖曳鼠标可以绘制线条。from tkinter import * def paint(event): # 拖曳可以绘图 x1, y1 (event.x), (event.y) # 设置左下角坐标 x2, y2 (event.x), (event.y) # 设置右上角坐标 canvas.create_oval(x1, y1, x2, y2, fillblue) def cls(): canvas.delete(all) def cls(): canvas.delete(all) tk Tk() lab Label(tk, text拖曳鼠标可以绘图) # 建立标题 lab.pack() canvas Canvas(tk, width640, height300) # 建立画布 canvas.pack() btn Button(tk, text清除, commandcls) # 建立清除按钮 btn.pack(pady5) canvas.bind(B1-Motion, paint) tk.mainloop()执行结果上述程序第8行使用了delete()方法这个方法内部加上”all“可以删除所有绘制的图对此程序而言相当于清除画布。如果想要让所绘制的线条变粗可以适度将左上角的(x, y)坐标减1右下角的(x, y)坐标加1。19-3 动画设计19-3-1 基本动画动画设计所使用的方法是move()使用格式如下。canvas.move(ID, xMove, yMove) # ID是对象编号 canvas.update() # 强制重绘画布xMoveyMove分别是沿x和y轴移动距离单位是像素。程序实例ch19_16移动球的设计每次移动5像素。from tkinter import * import time tk Tk() canvas Canvas(tk, width500, height150) canvas.pack() canvas.create_oval(10, 50, 60, 100, fillyellow) for x in range(0, 80): canvas.move(1, 5, 0) # ID1 x轴移动5像素y轴不变 tk.update() # 强制tkinter重绘 time.sleep(0.05) tk.mainloop()执行结果上述程序执行时使用循环第11行相当于定义每隔0.05s移动一次。其实我们只要设置move()方法的参数就可以向任意方法移动。程序实例