在本文中,将介绍 tkinter Canvas 画布小部件以及如何在其上绘制各种对象。Canvas 画布小部件,可用于绘制图形,创建图形编辑器,并实现各种自定义小部件。

要创建画布小部件,使用如下构造函数。
tk.Canvas(master, **options)
画布小部件是一个空白区域,可以在其上绘制图形、创建文本和放置图像等。
Canvas.create_oval(x1, y1, x2, y2, options = ...): 用于创建椭圆、圆。
Canvas.create_rectangle(x1, y1, x2, y2, options = ...): 用于创建矩形。
Canvas.create_arc(x1, y1, x2, y2, options = ...):用于创建扇形。
Canvas.create_polygon(coordinates, options = ...):用于创建任何多边形状。
canvas.create_line(x1, y1, x2, y2, options = ...):用于画线。
canvas.create_image(x, y, image=..., options = ... ) 添加图像。
canvas.create_bitmap(x, y, bitmap=..., options = ...) 添加位图。
canvas.create_text(x, y, text=..., options = ...) 添加文本。
绘制基本形状
import tkinter as tkroot = tk.Tk()root.geometry('600x400+200+200')root.title('Canvas 画布演示')canvas = tk.Canvas(root, width = 550, height = 350, bg='white', relief='sunken', bd=4)canvas.create_oval(10, 100, 90, 180, outline = "black", fill = "red", width = 2) # 圆形canvas.create_oval(110, 100, 210, 180, outline = "red", fill = "green", width = 2) # 椭圆canvas.create_rectangle(230, 100, 290, 160, outline = "black", fill = "blue", width = 2) # 矩形canvas.create_arc(310, 100, 390, 180, start = 0, extent = 210, outline = "green", fill = "red", width = 2) # 扇形points1 = [(10, 200), (180, 220), (330, 200)]canvas.create_line(points1, fill='black') # 画线points2 = [(410, 100), (480, 220), (530, 130)]canvas.create_polygon(points2, outline = "blue", fill = "orange", width = 2) # 多边形canvas.pack(anchor=tk.CENTER, expand=True)root.mainloop()

绘制图片
import tkinter as tkroot = tk.Tk()root.geometry('600x400+200+200')root.title('Canvas 画布演示')canvas = tk.Canvas(root, width = 550, height = 350, bg='white', relief='sunken', bd=4)photo = tk.PhotoImage(file="1.png")image = tk.PhotoImage(file="11.png")canvas.create_image(100, 100, image=photo, activeimage=image)canvas.pack(anchor=tk.CENTER, expand=True)root.mainloop()
使用 activeimage 参数,可以指定另一张图片,当鼠标指针移到图片上时,实现图片切换效果。

绘制文字
import tkinter as tkroot = tk.Tk()root.geometry('600x400+200+200')root.title('Canvas 画布演示') canvas = tk.Canvas(root, width = 550, height = 350, bg='white', relief='sunken', bd=4, selectbackground='pink', selectforeground='white', selectborderwidth=2)logo = tk.PhotoImage(file="logo.png")canvas.create_image(100, 50, image=logo)canvas.create_text(300, 50, text="Python之家 PythonHome.cn", fill='black', font=("黑体", 20), tag='text')canvas.select_from('text', 0)canvas.select_to('text', 7)canvas.pack(anchor=tk.CENTER, expand=True)root.mainloop()
使用 select_from 和 select_to 方法可以选择部分文字设置不同样式,样式在 Canvas 创建时指定。

绘制位图
import tkinter as tkroot = tk.Tk()root.geometry('600x400+200+200')root.title('Canvas 画布演示')canvas = tk.Canvas(root, width = 550, height = 350, bg='white', relief='sunken', bd=4)canvas.create_bitmap(250, 100, bitmap="error")canvas.create_bitmap(270, 100, bitmap="gray75")canvas.create_bitmap(290, 100, bitmap="gray50")canvas.create_bitmap(310, 100, bitmap="gray25")canvas.create_bitmap(330, 100, bitmap="gray12")canvas.create_bitmap(350, 100, bitmap="hourglass")canvas.create_bitmap(370, 100, bitmap="info")canvas.create_bitmap(390, 100, bitmap="questhead")canvas.create_bitmap(410, 100, bitmap="question")canvas.create_bitmap(430, 100, bitmap="warning")canvas.pack(anchor=tk.CENTER, expand=True)root.mainloop()

绘制小部件
import tkinter as tkroot = tk.Tk()root.geometry('600x400+200+200')root.title('Canvas 画布演示')def draw(): canvas.create_oval(10, 10, 140, 140, tag="oval")def erase(): canvas.delete("oval")canvas = tk.Canvas(root, width = 550, height = 350, bg='white', relief='sunken', bd=4)canvas.create_window(200, 300, window=tk.Button(text='画圆', command=draw, height=3, width=15))canvas.create_window(350, 300, window=tk.Button(text='删除', command=erase, height=3, width=15))canvas.pack(anchor=tk.CENTER, expand=True)root.mainloop()
绘制的每个对象都可以设置 tag 参数。如果指定了此参数,则可以在绘制后将对象删除。

添加滚动条
import tkinter as tkroot = tk.Tk()root.geometry('600x400+200+200')root.title('Canvas 画布演示')xbar = tk.Scrollbar(root, orient=tk.HORIZONTAL)ybar = tk.Scrollbar(root, orient=tk.VERTICAL) canvas = tk.Canvas(root, width = 550, height = 350, bg='white', scrollregion=(-50, -50, 600, 600), xscrollcommand=xbar.set, yscrollcommand=ybar.set,)canvas.grid(row=0, column=0)xbar.grid(row=1, column=0, sticky=tk.W+tk.E)ybar.grid(row=0, column=1, sticky=tk.N+tk.S)xbar['command'] = canvas.xviewybar['command'] = canvas.yviewcanvas.create_oval(10, 100, 90, 180, outline = "black", fill = "red", width = 2)canvas.create_oval(10, 300, 690, 380, outline = "black", fill = "red", width = 2)root.mainloop()

其他常用选项
选项
说明
activefill
当鼠标光标移动到绘制的对象上时,改变填充颜色。
activeoutline
当鼠标光标移动到绘制的对象上时,改变边框颜色。
activewidth
当鼠标光标移动到绘制的对象上时,改变线条粗细。
activedash
当鼠标光标移动到绘制的对象上时,变为虚线。
arrow
画线时添加箭头。起点 tk.FIRST,两端 tk.BOTH,末端tk.LAST。
arrowshape
画线时箭头形状。
dash
绘制虚线。
activeimage
当鼠标光标移动到显示的图像上时,将切换显示另一张图像。
tag
向绘制的对象添加标签。 利用标签可以轻松删除对象。