小言_互联网的博客

tkinter canvas绘图全攻略(图形项、配置参数和案例详解)

444人阅读  评论(0)

正在尝试着做一个比较完善的画图软件,计划使用tkinter库中的canvas控件来做,然后正在攻关canvas控件的相关知识,因此作为这个画图软件的附带产出物,整理成了本篇博文,分享给大家,一起研究研究,期待能对你工作带来启发和帮助。

不忘初心,方得始终,让我们一起共勉!

好的,言归正传,回归本篇博文的主题:tkinter canvas绘图全攻略(图形项、配置参数和案例详解)

Tkinter提供了Canvas 控件来实现绘图,在 Canvas 中可以绘制直线、矩形、椭圆等各种几何图形,也可绘制图片、文字、UI 组件(如 Button)等。Canvas 允许重新改变这些图形的属性,比如改变其坐标、外观、大小、位置等。

(一)图形绘制

Canvas 组件的用法与其他 GUI 组件一样简单,程序只要创建并添加 Canvas 组件,然后调用该组件的方法来绘制图形即可。


  
  1. from tkinter import *
  2. root =Tk()
  3. root.title( '我的第一个canvas窗口')
  4. cv =Canvas(root,width= 500,height= 500)
  5. cv.pack(fill=BOTH, expand=YES)
  6. oval1 = cv.create_oval( 100, 100, 300, 300,
  7. outline= 'yellow', # 边框颜色
  8. fill= 'pink', # 填充颜色
  9. width= 4 # 边框宽度
  10. )
  11. print(oval1)
  12. 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 方法有效。

基于上面的选项,抽取了几个配置项,然后演示一个略微复杂的案例(大家也可以自行进行参数修改,查看运行效果)。


  
  1. from tkinter import *
  2. root =Tk()
  3. root.title( '我的第二个canvas窗口(绘制矩形)')
  4. cv =Canvas(root,width= 780,height= 160,background= 'white')
  5. cv.pack(fill=BOTH, expand=YES)
  6. columnFont =( '微软雅黑', 18)
  7. # 使用循环绘制文字
  8. for i, st in enumerate([ '默认选项', '指定边宽', '指定填充', '边框颜色', '位图填充']):
  9. cv.create_text(( 50+ i * 140, 30),text = st,
  10. font = columnFont,
  11. fill= 'gray',
  12. anchor = W,
  13. justify = LEFT)
  14. options =[( None, None, None, None),
  15. ( 4, None, None, None),
  16. ( 4, 'pink', None, None),
  17. ( 4, 'pink', 'blue', None),
  18. ( 4, 'pink', 'blue', 'error')]
  19. # 采用循环绘制5个矩形
  20. for i, op in enumerate(options):
  21. cv.create_rectangle( 50+ i * 140, 60, 160+ i * 140, 120,
  22. width = op[ 0], # 边框宽度
  23. fill = op[ 1], # 填充颜色
  24. outline = op[ 2], # 边框颜色
  25. stipple = op[ 3]) # 使用位图填充
  26. 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()方法进行事件绑定响应的。

案例一:矩形框事件响应


  
  1. from tkinter import *
  2. from tkinter import messagebox
  3. def test(event):
  4. messagebox.showinfo(message= '你点击了矩形框!')
  5. root =Tk()
  6. root.title( '我的第三个canvas窗口(tag_bind()绑定事件')
  7. cv =Canvas(root,bg = 'white')
  8. cv.pack()
  9. cv.create_rectangle( 30, 30, 220, 150,
  10. width = 8,outline= 'red', # 边框颜色
  11. tags =( 'r1'),fill= 'pink')
  12. # 为指定图形项的左键单击事件绑定处理函数
  13. cv.tag_bind( 'r1', '<Button-1>', test)
  14. root.mainloop()

具体运行效果如下:

案例二:canvas图形框大小随着窗口变化而动态变化


  
  1. from tkinter import *
  2. def on_resize(event):
  3. # determine the ratio of old width/height to new width/height
  4. wscale = float(event.width) / cv.winfo_reqwidth()
  5. hscale = float(event.height) / cv.winfo_reqheight()
  6. cv.config(width=event.width,height=event.height)
  7. cv.scale( "all", 0, 0, wscale, hscale)
  8. root =Tk()
  9. root.title( '我的第三个canvas窗口(resize窗口)')
  10. cv =Canvas(root,width= 500,height= 500, highlightthickness= 0)
  11. cv.pack(fill=BOTH, expand=YES)
  12. oval1 = cv.create_oval( 150, 150, 350, 350,
  13. outline= 'yellow', # 边框颜色
  14. fill= 'pink', # 填充颜色
  15. width= 4 # 边框宽度
  16. )
  17. cv.addtag_all( "all")
  18. cv.bind( "<Configure>", on_resize)
  19. root.mainloop()

具体运行效果如下:

好的,这篇博文写完了,主要是对canvas的基础知识进行介绍,canvas控件功能很强大,后续的绘图软件将会使用到上述的技术进行建设,敬请期待和关注!也欢迎关注我的公众号(俊哥随笔),一起共同成长!


转载:https://blog.csdn.net/dhjabc_1/article/details/105449496
查看评论
* 以上用户言论只代表其个人观点,不代表本网站的观点或立场