绘制几何图形
| 方法 | create_line | create_rectangle | create_oval | create_arc | create_polygon |
|---|---|---|---|---|---|
| 图形 | 直线 | 矩形 | 椭圆 | 弧 | 多边形 |
| 坐标点 | 起点 + 终点 | 左上角 + 右下角 | 所有点 |
- 椭圆为同坐标点矩形的内切椭圆,弧为椭圆的一部分
通用参数
| 通用参数 | fill | outline | width | dash | stipple |
|---|---|---|---|---|---|
| 含义 | 填充颜色 | 边框颜色 | 边框宽度 | 虚线边框 | 用位图填充 |
- dash中,单个整数表示实线的长度,多个整数中,奇数位表实线长度,偶数位表间隔长度
a = Canvas(win)
a.pack()
p = (10, 10, 100, 100)
a.create_line(p, dash=(10,20,30,40))
a.create_rectangle(p, fill='blue', stipple='questhead')
a.create_oval(p, outline='blue')
a.create_arc(p, width=3)
a.create_polygon(0, 0, 0, 100, 100, 100)

专属参数
| 分类 | 参数 | 含义 | 说明 |
|---|---|---|---|
| 直线 | arrow | 两端是否有箭头 | NONE, FIRST, LAST, BOTH |
| arrowshap | 箭头形状 | 3个整数依次为填充长度、箭头长、宽 | |
| joinstyle | 拐角造型 | 尖MITER,圆ROUND,平BEVEL | |
| 弧 | start | 起始角度 | 默认值为0,3点钟方向 |
| extent | 逆时针转过的角度 | 默认值为90 | |
| style | 样式(默认为扇形) | 扇形PIESLICE,弓形CHORD,弧形ARC |
a.create_line(p, arrow=FIRST, arrowshap=(10,20,30))
a.create_line(p, 10, 100, width=10, joinstyle=BEVEL)
a.create_arc(p, style=ARC)
a.create_arc(p, style=CHORD)
a.create_arc(p, start=90, extent=180)

绘制其它图形
只需要一个坐标点
| 方法 | create_text | create_bitmap | create_image | create_window |
|---|---|---|---|---|
| 绘制内容 | 文本 | 位图 | 图像 | 组件 |
绘制文本 create_text
| 参数 | text | width | fill | font | anchor | justify |
|---|---|---|---|---|---|---|
| 含义 | 文本 | 宽度 | 字体颜色 | 字体格式 | 对齐方式 | 多行文本对齐方式 |
| 默认值 | - | - | black | - | CENTER | LEFT |
p = (30, 30)
a.create_text(p, text="示例文本", font=('Arial', '12', 'bold'))
a.create_text(p, text="示例文本", fill='blue', anchor=W)
a.create_text(p, text="示例文本", width=50, justify=CENTER)

绘制图片 create_bitmap + create_image
对gif图片,canvas的create_image()方法只能读取到动图的一帧
a.create_bitmap(p, bitmap='info')
i = PhotoImage(file='image.png')
a.create_image(p, image=i)

绘制组件 create_window
位置是部件中心点的坐标
button = Button(a, text="按钮1")
button.pack()
a.create_window(p, window=button, anchor=W)

查找图层ID
绘制图形时,Canvas会自动创建图形ID,依次为1,2,…,新绘制的图形位于上层
| 分类 | 参数 | 方法 | 返回的图形ID |
|---|---|---|---|
| 查找所有ID | 无 | find_all | 全部(元组形式) |
| 根据ID查找ID | tagOrId | find_withtag | 本身 |
| find_above | 上一层 | ||
| find_below | 下一层 | ||
| 根据坐标查找ID | x, y | find_closest | 离坐标最近的 |
| x1, y1, x2, y2 | find_enclosed | 矩形区域内部的所有图形 | |
| find_overlapping | 矩形区域重合的所有图形 |
a = Canvas(win)
a.pack()
p = (0, 0, 100, 100)
a.create_rectangle(p) #ID=1
a.create_oval(p) #ID=2
a.create_line(p) #ID=3
a.find_all() #(1, 2, 3)
a.find_withtag(2) #(2,)
a.find_above(2) #(3,)
a.find_below(2) #(1,)
a.find_closest(100, 0) #(1,)
a.find_closest(100, 50) #(2,)
a.find_closest(0, 0) #(3,)
a.find_enclosed(0, 0, 100, 100) #()
a.find_enclosed(-1, -1, 101, 101) #(1, 2, 3)
a.find_overlapping(0, 0, 100, 100) #(1, 2, 3)

图形的标签 tag
为图形添加标签,可以更方便地调用、处理图形。
一个图形可以有多个标签,一个标签可以对应多个图形。
根据ID添加标签
| 方法 | 对应的查找方法 | 参数 |
|---|---|---|
| addtag_all | find_all | newtag |
| addtag_withtag | find_withtag | newtag, tagOrId |
| addtag_above | find_above | |
| addtag_below | find_below | |
| addtag_closest | find_closest | newtag,x, y |
| addtag_enclosed | find_enclosed | newtag,x1, y1, x2, y2 |
| addtag_overlapping | find_overlapping |
a.addtag_all('通用标签')
a.addtag_withtag("正方形", 1)
a.addtag_withtag("圆", 2)
a.addtag_withtag("直线", 3)
获取图形所有标签:gettags(tagOrId)
找到第一个带某标签的图形,返回其所有标签,查找从最小的ID开始
a.gettags(1) #('通用标签', '正方形') 根据ID获取标签
a.gettags('正方形') #('通用标签', '正方形') 根据标签获取所有标签
a.gettags('通用标签') #('通用标签', '正方形')
删除标签:dtag(tag)
a.dtag('正方形')
a.gettags('通用标签') #('通用标签',)
修改图形
叠放次序
| 方法 | 作用 | 参数 |
|---|---|---|
| tag_raise | 图形上移 | 移动的图形(tagOrId),*指定图形(tagOrId) 不指定图形时,移至顶层/底层 |
| tag_lower | 图形下移 |
a.tag_lower(3)
a.gettags('通用标签') #('通用标签', '直线')—直线移到底层后,先找到直线
a.tag_lower(1, 3)
a.gettags('通用标签') #('通用标签', '圆')——正方形移到直线的下层后,先找到圆
选项值
获取:itemcget(tagOrId, option)
配置:item.config(tagOrId, cnf=None, **kw)
p = (10, 10, 100, 100)
a.create_rectangle(p, fill='pink')
a.itemcget(1, 'fill') #pink
a.itemconfig(1, fill='grey')

大小与位置
| 方法 | 参数 | 作用 |
|---|---|---|
| coords() | 图形名称,坐标 | 重设大小、位置 |
| move() | 图形名称,x位移,y位移 | 移动 |
| scale() | (a, b, c, d) | 锁定(a, b)坐标点,x, y方向分别缩放 x%, y% |
| delete() | tagOrId | 删除图形 |
p = (10, 10, 100, 100)
rect = a.create_rectangle(p, fill='pink')
a.coords(rect, 50, 50, 100, 100) #重设大小、位置
a.move(rect, 30, 10) #x,y方向移动距离
a.scale(rect, 100,100,0.5, 1) #锁定(100,100)坐标点,x方向缩放50%
a.delete(rect)

删除
| 方法 | 参数 | 作用 |
|---|---|---|
| delete() | tagOrId | 删除图形 |
| dchars() | tagOrId, start, end | 删除create_text创建的图形中的部分文字 |
p = (30, 30)
t = a.create_text(p, text="示例文本")
a.dchars(t, 2)
a.dchars(t, 1, 3)

绑定事件 tag_bind()
参数:tag, 事件, command, add=False
add=True:增加一个事件处理函数
add=False(默认):取代原来的事件处理函数
p = (10, 10, 100, 100)
rect = a.create_rectangle(p, fill='pink')
a.tag_bind(rect, "<Button-1>", lambda event:print(1))
a.tag_bind(rect, "<Button-1>", lambda event:print(2), add=True)
#点击图形时,同时输入【1】和【2】。如果图形没有fill,只有在点击边框时激发命令

绘制动画
创建一个球
from tkinter import *
win = Tk()
cv = Canvas(win, background='white', width=500, height=500)
cv.pack()
pic = PhotoImage(file='images/ball_1.gif')
ball = cv.create_image(250, 50, image=pic)
让球动起来
关闭窗口时报错:TclError: invalid command name “.!canvas”,可用try…except…跳过
import time
def moveball():
time.sleep(1)
cv.move(ball, 10, 10)
cv.update()
moveball() #重复自身
让球转起来
canvas不支持直接引用gif图片,可引用不同的图片实现动图效果
def moveball(i):
if i == 3: i = 0
else: i = i + 1
cv.itemconfig(ball, image=pics[i])
pics = [ PhotoImage(file='images/ball_%d.gif' % i) for i in range(4) ]
i = 0
ball = cv.create_image(250, 50, image=pics[i])
总程序
from tkinter import *
import time
def moveball(i):
if i == 3: i = 0
else: i = i + 1
cv.itemconfig(ball, image=pics[i])
cv.move(ball, 10, 10)
cv.update()
time.sleep(0.1)
moveball(i)
win = Tk()
cv = Canvas(win, background='white', width=500, height=500)
cv.pack()
pics = [ PhotoImage(file='images/ball_%d.gif' % i) for i in range(4) ]
i = 0
ball = cv.create_image(250, 50, image=pics[i])
moveball(i)


本章节详细介绍了如何使用Python的Tkinter库中的Canvas组件进行图形绘制,包括几何图形、文本、图片以及组件的创建。内容涵盖图形的通用参数、专属参数、标签管理、事件绑定以及创建动态效果如移动和旋转的动画。通过实例展示了如何创建并操作图形,以及处理图形动画的实现方法。
3万+

被折叠的 条评论
为什么被折叠?



