在前文tkinter-place详解中,讲解anchor属性时,用到了canvas。如果你不知道什么时canvas,精读本文就对了!
canvas的中文意思就是"画布"。在GUI中,canvas是一个非常基础的概念,基本上任何跟GUI相关的编程语言、库、框架等,都会有canvas,只要搞懂了canvas是什么,就一通百通了。
首先,我通俗的解释一下什么是canvas。就像画油画一样,得先准备一张画布,然后再在这张画布上进行创作,你可以在画布上画任何你想画的东西,直线、圆、椭圆等。在tkinter中,canvas就是类似的作用。提供给你一张"画布",你可以在上面"画"任何基础图形,也可以"画"其他控件。
Canvas(master, cnf={}, **kw)
想画画,通常要选择一个指定大小的画布,canvas可以通过属性width、height来选择canvas的尺寸。
指定 canvas的宽度
指定 canvas的高度
指定 canvas的背景颜色
from tkinter import (Tk, Button, Canvas)from tkinter.constants import RIGHT, LEFT, X, Y, BOTHmain_win = Tk()main_win.title('渔道的canvas')width = 300 height = 300 main_win.geometry(f'{width}x{height}')cav = Canvas(main_win, width=width, height=height, bg='blue')cav.pack()main_win.mainloop()
可以看到,生成了一张和主窗口一样尺寸的蓝色画布。
指定 鼠标的显示样式,当鼠标落在画布区域时。样式的值是arrow’, ‘watch’, ‘cross’.
指定边框样式,默认样式为’flat’,样式的种类有:‘flat’, ‘groove’, ‘raised’, ‘ridge’, ‘solid’, ‘sunken’
canvas的属性非常多哈,不可能一一列举,下面还是介绍一下实例,来辅助熟悉canvas的使用。
create_line(*args, **kw)
args参数为x1,y1,…,xn,yn 坐标值
kw参数为其他属性,fill用来填充直线的颜色;outline 为外围轮廓的颜色 ,width为线宽
cav = Canvas(main_win, width=width, height=height, bg='white')cav.pack()cav.create_line(0,height/2,width/4,height/4,width/2,height/2,(width/4)*3,(height/4)*3,width,height/2,fill='#ff0000')cav.create_line(0,height/2,width,height/2,fill='#ff0000')
create_oval(*args, **kw):
args参数 为x1,y1,x2,y2;坐标(x1,y1),(x2,y2)指定一个矩形(正方形)的左上角和右下角。圆或椭圆就在这个矩形内部。
kw参数为其他属性,如fill,outline,width
cav = Canvas(main_win, width=width, height=height, bg='white')cav.pack()cav.create_oval(75,75, 225,225, fill='blue', outline='yellow',width=5)cav.create_rectangle(75,75, 225,225,outline='red')
cav = Canvas(main_win, width=width, height=height, bg='white')cav.pack()cav.create_oval(55,85, 225,200, fill='blue', outline='yellow',width=5)
create_rectangle(*args, **kw)
args参数 为x1,y1,x2,y2;坐标(x1,y1),(x2,y2)指定一个矩形(正方形)的左上角和右下角。
kw参数为其他属性,如fill,outline,width
cav = Canvas(main_win, width=width, height=height, bg='white')cav.pack()cav.create_rectangle(75,75, 225,225,outline='red')cav.create_rectangle(85,85, 215,215,outline='blue', width=5)cav.create_rectangle(95,95, 205,205,fill='purple')
create_polygon( *args, **kw)
args参数为x1,y1,…,xn,yn 坐标值
kw参数为其他属性,fill用来设置直线的颜色;
使用游戏中的角色属性雷达图,来演示多边形的使用。
from math import (sin, cos, pi)cav = Canvas(main_win, width=width, height=height, bg='white')cav.pack()# x,y,r,angle,directdef set_point(x,y,r,angle=0,direct='n'): if direct == 'n': point = (x,y-r) elif direct == 'en': point = (x+r*sin(angle), y-r*cos(angle)) elif direct == 'es': point = (x+r*sin(angle), y+r*cos(angle)) elif direct == 's': point = (x,y+r) elif direct == 'ws': point = (x-r*sin(angle), y+r*cos(angle)) elif direct == 'wn': point = (x-r*sin(angle), y-r*cos(angle)) return pointcenter_x=width/2center_y=height/2r = 100radar_angle = pi/3n_point = set_point(center_x, center_y, r, direct='n')en_point = set_point(center_x, center_y, r, radar_angle, 'en')es_point = set_point(center_x, center_y, r, radar_angle, 'es')s_point = set_point(center_x, center_y, r, direct='s')ws_point = set_point(center_x, center_y, r, radar_angle,'ws')wn_point = set_point(center_x, center_y, r, radar_angle,'wn')cav.create_polygon(*n_point, *en_point, *es_point, *s_point, *ws_point, *wn_point, fill='gray')cav.create_text(*n_point, text='攻击力', fill='blue')cav.create_text(*en_point, text ='防御力', fill='blue')cav.create_text(*es_point, text='力量', fill='blue')cav.create_text(*s_point, text='敏捷', fill='blue')cav.create_text(*ws_point, text='智力', fill='blue')cav.create_text(*wn_point, text='魔法值', fill='blue')cav.create_line(*wn_point, *es_point, dash=(1,1))cav.create_line(*n_point, *s_point, dash=(1,1))cav.create_line(*en_point, *ws_point, dash=(1,1))# 粉色表示角色A的属性r = 50n_point = set_point(center_x, center_y, r+30, direct='n')en_point = set_point(center_x, center_y, r+6 , radar_angle, 'en')es_point = set_point(center_x, center_y, r+20, radar_angle, 'es')s_point = set_point(center_x, center_y, r , direct='s')ws_point = set_point(center_x, center_y, r+30, radar_angle,'ws')wn_point = set_point(center_x, center_y, r , radar_angle,'wn')cav.create_polygon(*n_point, *en_point, *es_point, *s_point, *ws_point, *wn_point, fill='#FFC0CB')# 红色表示角色B的属性r = 70n_point = set_point(center_x, center_y, r, direct='n')en_point = set_point(center_x, center_y, r, radar_angle, 'en')es_point = set_point(center_x, center_y, r, radar_angle, 'es')s_point = set_point(center_x, center_y, r, direct='s')ws_point = set_point(center_x, center_y, r+20,radar_angle,'ws')wn_point = set_point(center_x, center_y, r,radar_angle,'wn')cav.create_polygon(*n_point, *en_point, *es_point, *s_point, *ws_point, *wn_point, fill='', outline='red')
create_arc(*args, **kw)
args参数为x1,y1,x2,y2 坐标值
kw参数为其他属性, start表示起始弧度,extent表示结束弧度。
根据初中的几何知识,圆弧是由射线绕它的端点旋转,在旋转过程中射线上的点会形成一条狐。
看着create_arc函数的参数,我们可能会想,画弧线,那得指定起点(端点),指定弧度,怎样设置呢?
cav = Canvas(main_win, width=width, height=height, bg='white')cav.pack()cav.create_line(0,height/2,width,height/2,fill='#ff0000')cav.create_line(width/2,0,width/2,height,fill='#ff0000')cav.create_arc(100, 150, 150, 200, start=0, extent=320)cav.create_rectangle(100,150,150,200,outline='red') # 画一个矩形,方便描述
上面的示例代码中,(x1,y1)=(100,150),(x2,y2)=(150,200),刚好形成一个矩形,那么圆弧的起点(端点)就是矩形的中心点,半径为(x2-x1)/2,射线绕端点(中心点)逆时针从start弧度旋转到extent弧度。这就形成了下图所示的圆弧。
create_text(*args, **kw)
args参数为x1,y1,x2,y2 坐标值
kw参数为其他属性,如fill,outline,width,font
在画多边形
小节中,其实已经使用过该函数。
cav = Canvas(main_win, width=width, height=height, bg='white')cav.pack()cav.create_text(100,100, text='渔道', fill='blue')cav.create_text(100,150, text='python', fill='red', font=('Courier', 20, 'bold'))
create_image(*args, **kw)
png = PhotoImage(file='qq.png')width = png.width()height = png.height()main_win.geometry(f'{width}x{height}')cav = Canvas(main_win, width=width, height=height, bg='blue')cav.pack()cav.create_image(0,0,anchor='nw', image=png)
到目前为止,介绍的都是静态的显示效果,如果想让画面动起来,应该怎么做呢?
canvas提供了这种机制,可以让图形"动"起来。
import timecanvas = Canvas(main_win,width=width,height=height)canvas.pack()arc = canvas.create_arc(10, 50, 50, 100, start=30, extent=320)for x in range(0,60): canvas.move(arc,5,0) main_win.update() time.sleep(0.05)main_win.mainloop()
canvas的内容非常的多,本文先介绍到这里。
联系客服