正在尝试着做一个比较完善的画图软件,计划使用tkinter库中的canvas控件来做,然后正在攻关canvas控件的相关知识,因此作为这个画图软件的附带产出物,整理成了本篇博文,分享给大家,一起研究研究,期待能对你工作带来启发和帮助。
不忘初心,方得始终,让我们一起共勉!
好的,言归正传,回归本篇博文的主题:tkinter canvas绘图全攻略(图形项、配置参数和案例详解)
Tkinter提供了Canvas 控件来实现绘图,在 Canvas 中可以绘制直线、矩形、椭圆等各种几何图形,也可绘制图片、文字、UI 组件(如 Button)等。Canvas 允许重新改变这些图形的属性,比如改变其坐标、外观、大小、位置等。
(一)图形绘制
Canvas 组件的用法与其他 GUI 组件一样简单,程序只要创建并添加 Canvas 组件,然后调用该组件的方法来绘制图形即可。
-
from tkinter
import *
-
root =Tk()
-
root.title(
'我的第一个canvas窗口')
-
cv =Canvas(root,width=
500,height=
500)
-
cv.pack(fill=BOTH, expand=YES)
-
oval1 = cv.create_oval(
100,
100,
300,
300,
-
outline=
'yellow',
# 边框颜色
-
fill=
'pink',
# 填充颜色
-
width=
4
# 边框宽度
-
)
-
print(oval1)
-
root.mainloop()
运行效果如下:
Canvas 提供了 create_oval() 方法绘制椭圆(包括圆,圆是椭圆的特例)。 实际上,Canvas 还提供了如下方法来绘制各种图形:
create_rectangle() :绘制矩形
create_arc:绘制弧。
create_bitmap:绘制位图。
create_image:绘制图片。
create_line():绘制直线。
create_polygon:绘制多边形。
create_text:绘制文字。
create_window:绘制组件。
在绘制这些图形时可指定如下属性选项进行更丰富的控件配置:
fill:指定填充颜色。如果不指定该选项,默认不填充。
outline:指定边框颜色。
width:指定边框宽度。如果不指定该选项,边框宽度默认为 1。
dash:指定边框使用虚线。该属性值既可为单独的整数,用于指定虚线中线段的长度;也可为形如(5,2,3)格式的元素,此时5 指定虚线中线段的长度,2 指定间隔长度,3 指定虚线长度……依此类推。
stipple:使用位图平铺进行填充。该选项可与 fill 选项结合使用,fill 选项用于指定位图的颜色。
style:指定绘制弧的样式。该选项仅对 create_arc 方法起作用。该选项支持 PIESLICE(扇形)、CHORD(弓形)、ARC(仅绘制弧)选项值。
start:指定绘制弧的起始角度。该选项仅对 create_arc 方法起作用。
extent:指定绘制弧的角度。该选项仅对 create_arc 方法起作用。
arrow:指定绘制直线时两端是否有箭头。该选项支持 NONE(两端无箭头)、FIRST(开始端有箭头)、LAST(结束端有箭头)、BOTH(两端都有箭头)选项值。
arrowshape:指定箭头形状。该选项是一个形如 "20 20 10" 的字符串,字符串中的三个整数依次指定填充长度、箭头长度、箭头宽度。
joinstyle:指定直接连接点的风格。仅对绘制直线和多向形有效。该选项支持 METTER、ROUND、BEVEL 选项值。 • anchor:指定绘制文字、GUI 组件的位置。该选项仅对 create_text()、create_window() 方法有效。
justify:指定文字的对齐方式。该选项支持 CENTER、LEFT、RIGHT 常量值,该选项仅对 create_text 方法有效。
基于上面的选项,抽取了几个配置项,然后演示一个略微复杂的案例(大家也可以自行进行参数修改,查看运行效果)。
-
from tkinter
import *
-
root =Tk()
-
root.title(
'我的第二个canvas窗口(绘制矩形)')
-
cv =Canvas(root,width=
780,height=
160,background=
'white')
-
cv.pack(fill=BOTH, expand=YES)
-
-
columnFont =(
'微软雅黑',
18)
-
# 使用循环绘制文字
-
for i, st
in enumerate([
'默认选项',
'指定边宽',
'指定填充',
'边框颜色',
'位图填充']):
-
cv.create_text((
50+ i *
140,
30),text = st,
-
font = columnFont,
-
fill=
'gray',
-
anchor = W,
-
justify = LEFT)
-
-
options =[(
None,
None,
None,
None),
-
(
4,
None,
None,
None),
-
(
4,
'pink',
None,
None),
-
(
4,
'pink',
'blue',
None),
-
(
4,
'pink',
'blue',
'error')]
-
# 采用循环绘制5个矩形
-
for i, op
in enumerate(options):
-
cv.create_rectangle(
50+ i *
140,
60,
160+ i *
140,
120,
-
width = op[
0],
# 边框宽度
-
fill = op[
1],
# 填充颜色
-
outline = op[
2],
# 边框颜色
-
stipple = op[
3])
# 使用位图填充
-
-
root.mainloop()
运行效果如下:
二、不只是静态的图形
在 Canvas 中通过 create_xxx 方法绘制图形项之后,这些图形项井不是完全静态的图形,每个图形项都是一个独立的对象,程序完全可以动态地修改、删除这些图形项。
为了修改、删除这些图形项,程序需要先获得这些图形项的引用。
获得这些图形项的引用有两种方式:
1.通过图形项的 id,也就是 Canvas 执行 create_xxx() 方法的返回值。一般来说,create_xxx() 会依次返回 1、2、3 等整数作为图形项的 id。
2.通过图形项的 tag(标签)。
(一)TAG图形项配置
程序完全可以根据 tag 来新增、修改、获取或者操作图形项。
1、增加图形项:
addtag_all(self, newtag):为所有图形项添加新 tag。
addtag_closest(self, newtag, x, y):为和 x、y 点最接近的图形项添加新 tag。
addtag_enclosed(self, newtag, x1, y1, x2, y2):为指定矩形区域内最上面的图形项添加新tag。其中 x1、y1 确定矩形区域的左上角坐标;x2、y2 确定矩形区域的右下角坐标。
addtag_withtag(self, newtag, tagOrId):为 tagOrId 对应图形项添加新 tag。
2、删除图形项:
dtag(self, *args):删除指定图形项的tag。
3、获取图形项:
gettags(self, *args):获取指定图形项的所有tag。
find_withtag(self, tagOrId):获取tagOrId 对应的所有图形项。
4、操作图形项
在 Canvas 中获取图形项之后,接下来可通过 Canvas 提供的大量方法来操作图形项。
Canvas 以“堆叠”的形式来管理这些图形项,先绘制的图形项位于“堆叠”的下面,后绘制的图形项位于“堆叠”的上面。因此,如果两个图形项有重叠的部分,那么后绘制的图形项(位于上面)会遮挡先绘制的图形项。
总结起来,Canvas 提供了如下方法在图形项“堆叠”中查找图形项:
find_all(self):返回全部图形项。
find_closest(self, x, y):返回和 x 、y 点最接近的图形项。
find_enclosed(self, x1, y1, x2, y2):返回位于指定矩形区域内最上面的图形项。
find_overlapping(self, x1, y1, x2, y2):返回与指定矩形区域重叠的最上面的图形项。
find_withtag(self, tagOrId):返回 tagOrId 对应的全部图形项。
如果程序希望获取或修改图形项的选项,则可通过 Canvas 的如下方法来操作:
itemcget(self, tagOrId, option):获取tagOrId 对应图形项的option 选项值。
itemconfig(self, tagOrId, cnf=None, **kw):为tagOrId 对应图形项配置选项。
itemconfigure(self, tagOrId, cnf=None, **kw):该方法与上一个方法完全相同。
Canvas 提供了如下方法来改变图形项的大小和位置:
coords(self, *args):重设图形项的大小和位置。
move(self, *args):移动图形项,但不能改变大小。简单来说,就是在图形项的 x、y 基础上加上新的 mx、my 参数。
scale(self, *args):缩放图形项。该方法的 args 参数要传入 4 个值,其中前两个值指定缩放中心;后两个值指定 x、y 方向的缩放比。
(二)图形操作和事件响应
通过获取图形项的 id或者tag(标签),最大的目的就是可以对canvas上的图形获取到其引用,然后可以进行后续的相关操作(如改变图形的大小、进行移动、修改颜色等属性),但是具体如何操作,主要是根据我们自行设置的响应函数或者自带的默认响应函数相关,而且必须进行事件响应绑定。Canvas 提供了一个 tag_bind() 方法,该方法用于为指定图形项绑定事件处理函数或方法,这样图形项就可以响应用户动作了。
这里提供两个案例告诉大家如何操作tag_bind()方法进行事件绑定响应的。
案例一:矩形框事件响应
-
from tkinter
import *
-
from tkinter
import messagebox
-
-
def test(event):
-
messagebox.showinfo(message=
'你点击了矩形框!')
-
-
root =Tk()
-
root.title(
'我的第三个canvas窗口(tag_bind()绑定事件')
-
cv =Canvas(root,bg =
'white')
-
cv.pack()
-
cv.create_rectangle(
30,
30,
220,
150,
-
width =
8,outline=
'red',
# 边框颜色
-
tags =(
'r1'),fill=
'pink')
-
# 为指定图形项的左键单击事件绑定处理函数
-
cv.tag_bind(
'r1',
'<Button-1>', test)
-
root.mainloop()
具体运行效果如下:
案例二:canvas图形框大小随着窗口变化而动态变化
-
from tkinter
import *
-
-
def on_resize(event):
-
# determine the ratio of old width/height to new width/height
-
wscale = float(event.width) / cv.winfo_reqwidth()
-
hscale = float(event.height) / cv.winfo_reqheight()
-
cv.config(width=event.width,height=event.height)
-
cv.scale(
"all",
0,
0, wscale, hscale)
-
-
root =Tk()
-
root.title(
'我的第三个canvas窗口(resize窗口)')
-
cv =Canvas(root,width=
500,height=
500, highlightthickness=
0)
-
cv.pack(fill=BOTH, expand=YES)
-
oval1 = cv.create_oval(
150,
150,
350,
350,
-
outline=
'yellow',
# 边框颜色
-
fill=
'pink',
# 填充颜色
-
width=
4
# 边框宽度
-
)
-
-
cv.addtag_all(
"all")
-
cv.bind(
"<Configure>", on_resize)
-
-
root.mainloop()
具体运行效果如下:
好的,这篇博文写完了,主要是对canvas的基础知识进行介绍,canvas控件功能很强大,后续的绘图软件将会使用到上述的技术进行建设,敬请期待和关注!也欢迎关注我的公众号(俊哥随笔),一起共同成长!
转载:https://blog.csdn.net/dhjabc_1/article/details/105449496