tkinter的Canvas组件,绘画基本知识

news2025/1/12 1:55:43

一、说明

        画布组件是Tkinter画图的最重要组件。画布对象是几何绘制、动画绘制的不二选项,本文专门对画布Canvas进行详细描述,并配以适当代码支持。

二、tkinter的Canvas组件,绘画基本知识

        Canvas组件,可以用来绘图,也可以用来制作动画,绘图,可以绘线条,圆,方形,多边形,制作动画,这是制作游戏的基础。

        但Canvas组件要学习的东西很多,参数也多,我觉得,我们可以先学一些基础的东西,等了解基础知识后,再深入学习。

        在Canvas组件,既然画线,画方框,画多边形,画圆,画文字,画组件等对象,你可以把Canvas组件当成容器组件来看待,先用“画”的方式来在画布里创建线,圆,框,文字,组件等,然后,再可经为这个组件设置各种属性:如更改坐标,改变颜色,当然你可以删除这些对象。

        首先,我们先来学习如何如何创建画布,即Canvas组件。

2.1  画布生成语法

        Canvas(父组件,参数…….)

        先创建 一个浅蓝画布看看 

         Python

from tkinter import * 
root=Tk() 
can1=Canvas(root,width=200,height=150,background='lightblue')  # 浅蓝画布 
can1.pack() 
root.mainloop()

        运行结果生成一个浅蓝色的画布(默认的画布背景颜色是跟窗体背景颜色是一样的,不太好辨认边界)

2.2 绘制线条:

create_line(x1, y1, x2, y2, …… xn,yn, 参数)

(X1,Y1),(x2,y2) ……. (xn,yn)  是不同点的坐标,画线的过程就是 (X1,Y1),连接 (x2,y2),再连接(x3,y3), …….再连接 (xn,yn)。

参数:

arrow :

arrow=FIRST 起始点有箭头  arrow=LAST 最后一条线的末端有箭头

arrow=BOTH 2端都有箭头   默认是没有箭头

   

capstyle:

    线条末端的样式:BUTT,  PROJECTING,  ROUND  默认为BUTT

dash:

    画的线为虚线,虚线信息由元组来表现,元组的第1个数字为实线像素,第2个为空白像素,实线和空白交替使用元组的数字,用完后,再重新使用元组的第1个数字。如:

dash(5,1,1,1) 5像素的实线,1像素的空白,1像素的实线,1像素的空白

stipple: 绘制位图线条

widht : 线条宽度(粗细)

fill : 线条颜色

下面的代码来演示一下上面参数。

 Python

from tkinter import *
 
root=Tk()
 
can1=Canvas(root,width=220,height=150,background='lightblue') # 浅蓝画布
can1.pack(fill=BOTH,expand=True) 
 
can1.create_line(20,10,200,10) # 默认粗细线条
can1.create_line(20,35,200,35,width=5) # 粗线
can1.create_line(20,60,200,60,width=10,fill='red') # 红线
can1.create_line(20,85,200,85,dash=(5,2)) # 虚线
can1.create_line(20,110,200,110,arrow=BOTH) # 2端有箭头
can1.create_line(20,135,200,135,stipple='questhead',width=15) # 位图线
 
root.mainloop()

运行结果

      

1.PNG

2.3 绘制矩形:

create_rectangle(x1,y1, x2,y2, 参数)

(x1,y1) 和 (x2,y2)是矩形的左上角和右下角的坐标,由2个坐标决定矩形的大小。

参数:

dash: 矩形线条为虚线

fill :  矩形填充颜色

outline:矩形线条颜色

stipple:位图填充矩形

width: 矩形线条宽度

 Python

from tkinter import *
 
root=Tk()
 
can1=Canvas(root,width=220,height=150,background='lightblue') # 浅蓝画布
can1.pack(fill=BOTH,expand=True) 
 
can1.create_rectangle(30,10,90,60,fill='red',outline='green',width=4)  # 左上图
 
can1.create_rectangle(130,10,200,60,dash=(3,2)) # 右上图
 
can1.create_rectangle(20,80,100,140,stipple='questhead',
     fill='red', outline='blue',width=2) # 左下图
 
can1.create_rectangle(120,80,210,140,stipple='questhead',
     fill='blue', outline='red',width=2,dash=(3,2)) # 右下图
 
root.mainloop()

运行结果

2.PNG

2.4 绘制圆弧:

create_arc( x1,y1, x2,y2, extent=angle, sytle=ARC, 参数 )

(x1,y1) 和 (x2,y2)决定一个矩形的左上角和右下角的坐标,而这个矩形决定圆弧的形状(弧度)。

extent: 跨度,即从圆弧的起始益到结束位置的角度,默认为90,范围是1到359

style: 样式:扇形(‘pieslice’)  弓形(‘chord’) 弧形(‘arc’)  默认扇形

dash: 虚线

fill : 填充颜色

outline :圆弧线条颜色

start : 圆弧起始位置,默认益是圆弧的右边开始,方向是逆时针

stipple : 位图圆弧

width : 圆弧线条宽度(粗细)

其实create_arc() 方法可以创建:圆,圆弧,椭圆,椭圆弧。

(x1,y1) 和 (x2,y2)坐标来决定的是画圆和圆弧还是画椭圆及椭圆弧 

如果由这2对坐标参数决定的是一个正方形,那创建的就是这个正方形内的内切圆或圆弧;

如果由这2对坐标参数决定的是一个长方形,那创建的就是这个长方形内的内切椭圆或椭圆弧;

我来自wb86.com何老师的济亨网

下面的代码先画一个正方形,然后根据最上面的3项设置,用正方式同样的坐标画圆,圆弧,弓形,扇形,大家感受一下。 丶丌皛

 Python

from tkinter import *
 
root=Tk()
 
fr1=Frame(root,relief='ridge',borderwidth=1) # 不设置边线宽,无法显示
fr1.pack(fill=X)
fr2=Frame(root,relief='ridge',borderwidth=1) # 不设置边线宽,无法显示
fr2.pack()
 
var1=StringVar()
op1=OptionMenu(fr1,var1,'弓形','弧形','扇形').pack(side=LEFT,padx=20)
var1.set('弧形')
 
sca1=Scale(fr1,from_=0,to=359,orient=HORIZONTAL,label='起始偏移角度')
sca1.pack(side=LEFT,padx=20)
 
sca2=Scale(fr1,from_=0,to=359,orient=HORIZONTAL,label='圆心度(弧的跨度)')
sca2.pack(side=LEFT,padx=20)
 
def ok():
    can1.delete('all')  # 清除所有对象
    can1.create_rectangle(50,10,180,140,dash=(3,2)) # 画 正方形
    can1.create_line(115,0,115,150,dash=(3,2),fill='yellow') # 画 水平中线
    can1.create_line(40,75,190,75,dash=(3,2),fill='yellow') # 画 垂直中线
 
    a=var1.get()
    if a=='弓形':
        b='chord'
    elif a=='弧形':
        b='arc'
    elif a=='扇形':
        b='pieslice'
 
    can1.create_arc(50,10,180,140,style=b,start=sca1.get(),extent=sca2.get(),outline='red',width=4)
    # 根据参数的不同,生成不同的圆,圆弧(弓形,扇形)
 
but1=Button(fr2,text=" 画:圆、弧线 ",command=ok)
but1.pack()
 
can1=Canvas(fr2,width=220,height=150,background='lightblue') # 浅蓝画布
can1.pack(fill=BOTH,expand=True) 
 
ok()
 
root.mainloop()

运行后,调节3个参数的值,会出现不同形状,位置的圆弧。

3.PNG

圆心角调整到359度,就显示一个圆,但这个圆只有359度,仔细看,有缺角的。如果你调整到360度,其实就是0度,就什么都画不出来。

以下随便是选取一个偏移角度,再搭配弓形,扇形,画出来的图形。

注:水平黄线向右方向,是偏移0度,逆时针方向,可以0 - 359度偏移。

注意:fill 填充参数没有演示,这个参数填充颜色,只能是弓形和扇形才可以填充颜色。

举一反三,你可以把上面的代码,正方形的坐标改成长方形,就会画出椭圆,以及椭圆弧,在这里就不再演示了。

上面用画圆弧的方法画圆,其实只是一个大的圆弧,并不是真的圆,因为这个弧还是有一个缺口,现在我们来用新的方法画圆或椭圆。

2.5 绘制圆或椭圆:

create_oval( x1,y1, x2,y2, 参数 )

(x1,y1) 和 (x2,y2)坐标来决定的是画圆 还是画椭圆。

在这里的参数跟以上关于线条,弧度的参数相同,并没有太多的知识要讲,下面有代码来说明:

 Python

 
from tkinter import *
 
root=Tk()
 
can1=Canvas(root,width=270,height=150,background='lightblue') # 浅蓝画布
can1.pack()
 
can1.create_rectangle(20,10,150,140,dash=(3,2),outline='green') # 画 正方形
can1.create_oval(20,10,150,140,width=4,fill='lightyellow') # 画 圆,填充浅黄
 
can1.create_rectangle(160,10,250,140,dash=(3,2),outline='green') # 画 长方形
can1.create_oval(160,10,250,140,width=4,fill='lightgreen') # 画 椭圆,填充浅绿
 
root.mainloop()

 运行结果

6.PNG

2.6 绘制多边形:

create_polygon( x1,y1, x2,y2, …… xn,yn, 参数 )

上面的参数跟绘制线条很类似, 区别在于:

 

(X1,Y1),(x2,y2) ……. (xn,yn)  是不同点的坐标。

画线的过程就是 (X1,Y1),连接 (x2,y2),再连接(x3,y3), …….再连接 (xn,yn)。

画多边形就是:按画线过程,从起始点连接到结束点,但是要多一步,就是把结束点再连接起始点。

下面的代码,在绘制多边形的同时,在它的下方也绘制线条,你就可以看到多边形要连接起始点和结束点,而且可以填充颜色。

 Python

from tkinter import *
 
root=Tk()
 
can1=Canvas(root,width=460,height=200,background='lightblue') # 浅蓝画布
can1.pack(fill=BOTH,expand=True) 
 
can1.create_polygon(10,10, 100,10, 50,80,fill='',outline='red') # 红框,透明填充
can1.create_line(10,100, 100,100, 50,180, fill='red') # 画线
 
can1.create_polygon(120,10, 180,30, 250,50, 200,80, 130,70, fill='lightyellow',outline='blue') # 蓝框,浅黄填充
can1.create_line(120,100, 180,120, 250,140, 200,170, 130,160 ,fill='blue') # 画线
 
can1.create_polygon(260,10, 370,30, 440,70, 380,90, 320,80, outline='green',width=5) # 绿框,默认为黑色填充
can1.create_line(260,110, 370,130, 440,170, 380,190, 320,180, fill='green',width=5) # 画线
 
root.mainloop()

 运行结果

7.PNG

fill=’’ 表示多边形填充的是透明色。如果没有写fill这个参数,默认是填充黑色。

2.7 绘制文字:

create_text( x,y, text=字符文本, 参数 )

(x,y) 是字符文本在画布的坐标位置,但文本的起始位置要根据参数 anchor 来决定。

anchor 这个参数跟以前学的标签组件的anchor一样,有"n", "ne", "e", "se", "s", "sw", "w", "nw", 或 "center" 这9个选项,默认是center这个居中选项。

fill : 字符文本的颜色。

font : 字符文本的字体,大小。

justify : 多行显示时,靠那一边对齐。默认是LEFT

width : 这个参数类似于标签组件的wraplength参数,它决定在什么位置字符文本换行。

stipple : 指定一个位图用于填充,如果是空字符串,即字体为实心。

下面代码来演示一下,坐标和anchor 这2个参数来决定文本的显示位置

 Python

。
from tkinter import *
 
root=Tk()
 
can1=Canvas(root,width=240,height=100,background='lightblue') # 浅蓝画布
can1.pack(fill=BOTH,expand=True) 
 
can1.create_line(120,0, 120,100,fill='yellow') # 垂直中心线
can1.create_line(0,50, 240,50,fill='yellow') # 水平中心线
 
can1.create_text(120,50,text='中国在中间',font=('黑体',17,'bold'),fill='red') # anchor默认为center
can1.create_text(120,50,text='美国靠下边',font=('黑体',17,'bold'),fill='blue',anchor=NW)
 
root.mainloop()

运行结果:

8.PNG

“中国在中间”文本没有设置anchor参数,anchor默认为center,居中,这个文本的锚点是文本的正中间,正中间的坐标就是 x,y 这个坐标。

而“美国靠下边”这个文本,我设置anchor=NW,所以,这个文本的锚点为左上角,左上角的位置就是 x,y 这个坐标。

你只要把输入的文本当成一个标签组件的文本,整个画布当成这个标签的大小,就好理解了,anchor参数在画布以及标签组件的用法是一样的。

2.8 插入图片:

create_image( x,y, 参数 )

 (x,y) 是插入图片的坐标位置,但图片的位置要根据参数 anchor 来决定,这点跟上面的说的插入文本是完全一样的。

虽说是插入图片,你也可以当成是插入带图片的标签,所以插入的图片要先用 PhotoImage() 等方法来创建图片对象。

感觉没有太多的新知识要讲解,在这里就不用代码演示了。

2.9 插入组件:

create_window( x,y, 参数 )

(x,y) 坐标,anchor参数跟上面讲解知识完全一样。

window:这个参数又类似Text组件插入其他组件一样,插入的组件也一样可以响应事件。

下面的代码演示一下。

 Python

from tkinter import *
 
root=Tk()
 
can1=Canvas(root,width=240,height=100,background='lightblue') # 浅蓝画布
can1.pack(fill=BOTH,expand=True) 
 
can1.create_line(120,0, 120,100,fill='yellow') # 垂直中心线
can1.create_line(0,50, 240,50,fill='yellow') # 水平中心线
 
but1=Button(root,text="按钮",command=lambda:print('被点击了')) # 先创建按钮
ra1=Radiobutton(root,text='多选按钮') # 先创建多选按钮
 
can1.create_window(120,50,window=but1) # 在正中间插入按钮
can1.create_window(120,50,window=ra1,anchor=NW) # 插入多选按钮
 
root.mainloop()

运行结果:

9.PNG

下面是用代码来做一个简单的画图软件,这个软件可以设置画笔颜色,画笔粗细,清除画布。

代码里用到的颜色对话框,这个知识在以前的文章里讲解过了。

 Python

from tkinter import *
from tkinter.colorchooser import *
 
root=Tk() # 源码来自 wb98.com
 
fr1=Frame(root,relief='ridge',borderwidth=1) # 不设置边线宽,无法显示
fr1.pack(fill=X)
 
but1=Button(fr1,text="点击选择画笔颜色", relief='sunken', bg='red',
command=lambda:but1.config(bg=askcolor()[1])) # 点击弹出颜色对话框
but1.pack(side=LEFT,padx=20)
 
la1=Label(fr1,text='画笔粗细: ')
la1.pack(side=LEFT)
 
spin1=Spinbox(fr1,from_=1,to=20,width=6) # 画笔粗细
spin1.pack(side=LEFT)
 
but2=Button(fr1,text=" 清空画布 ",command=lambda:can1.delete('all')) # 清空画布
but2.pack(side=LEFT,padx=20)
 
can1 = Canvas(root,width=400, height=200,background='white') # 白底画布
can1.pack(fill=BOTH,expand=True)
 
def paint(event): # 鼠标点击画点 或 按下鼠标移动画线
    hb=int(spin1.get()) # hb是画笔的粗细
    x1, y1 = (event.x - hb), (event.y - hb)  # 圆的左上角坐标
    x2, y2 = (event.x + hb), (event.y + hb)  # 圆的右下角坐标
    can1.create_oval(x1, y1, x2, y2,fill=but1['bg'], outline=but1['bg']) # 画圆 连线
 
can1.bind("<B1-Motion>", paint) # 按下鼠标移动画画
can1.bind("<Button-1>",paint) # 点击鼠标右键画点
 
root.mainloop()

运行结果:

10.PNG

三、后记

        在tkinter中没有画点的方法,在上述代码中,是以画圆的方法来画点的,最小的粗细的画笔就是圆的左上角坐标跟右下角坐标是一样的。

        清除画面上的所有对象,用的方法是:delete('all')  所以,上面代码中用于清空画布的代码就是: can1. delete('all')

        Canvas组件还有一些参数没有说明,我自己也要慢慢学习,再来讲解。

        还有有关动画的方法也没有讲解,下一篇文章再简单地讲一下用Canvas组件动画初步。

此文章来自:wb98.com  网站还有相关的系列课程文章,感兴趣的可以前往。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1037319.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【Java 基础篇】Java反射详解:深入了解Java的镜像世界

Java是一门面向对象的编程语言&#xff0c;其强大之处之一就是能够在运行时检查、获取和操作类、方法、字段等程序元素。这一特性就是通过Java的反射机制实现的。本文将深入介绍Java反射&#xff0c;包括它的基本概念、使用方法、常见应用场景和注意事项。无需担心&#xff0c;…

云计算战略:选择适合你业务的云平台

文章目录 云计算的概述选择云平台的关键因素1. 业务需求2. 预算3. 性能要求4. 数据隐私和合规性 示例&#xff1a;选择适合的云平台业务需求预算性能要求数据隐私和合规性 代码示例&#xff1a;使用云平台服务结论 &#x1f389;欢迎来到云计算技术应用专栏~云计算战略&#xf…

“源启2.0”:从自上而下的解构,到自下而上的重构

从垂直打穿、到应用重构&#xff0c;中电金信赋能行业数字化转型之路既“向下走”、也“向上看”。“向上”先理解和吃透客户的企业战略&#xff0c;进而自上而下地将企业战略拆解为业务架构&#xff0c;“向下”再将业务架构拆解为应用架构和数据架构&#xff0c;并进一步对齐…

JS预解析/编译(变量提升):var(仅声明,无赋值)、function变量 创建作用域

目录 变量提升/预定义 function和var 重名&#xff1a;函数覆盖变量 不执行代码 重复声明&#xff1a;只提升一次 函数形参&#xff1a;变量提升 带 var 和不带 var 全局作用域&#xff1a; window 的属性 私有/函数作用域&#xff1a; 带 var 的是私有变量 IIFE 函…

Linux 终端与进程

有趣的问题 Linux 中的 终端&#xff0c;控制台&#xff0c;TTY&#xff0c;PTY 究竟是什么&#xff1f;它们与进程有什么关系&#xff1f; 历史回顾&#xff1a;控制台 (Console) 控制台是一个直接控制设备的面板 (属于设备的一部分) 计算机设备的控制台&#xff1a;按键 &…

2FSK调制解调VHDL,Quartus

名称&#xff1a;2FSK调制解调VHDL&#xff08;代码在文末付费下载&#xff09; 软件&#xff1a;Quartus 语言&#xff1a;VHDL 要求&#xff1a;使用VHDL实现2FSK的调制和解调&#xff0c;并进行仿真 代码下载&#xff1a;2FSK调制解调VHDL,Quartus_Verilog/VHDL资源下载…

C++ stack queue模拟实现

目录 一.stack 二.queue 三.deque STL中有6大组件&#xff0c;我们前面讲的string/vector/list是容器&#xff0c;还有迭代器&#xff0c;以及算法&#xff08;比如find&#xff0c;swap&#xff0c;reverse&#xff0c;sort&#xff0c;merge函数&#xff09;&#xff0c;仿函…

【Java 基础篇】Java Stream 流详解

Java Stream&#xff08;流&#xff09;是Java 8引入的一个强大的新特性&#xff0c;用于处理集合数据。它提供了一种更简洁、更灵活的方式来操作数据&#xff0c;可以大大提高代码的可读性和可维护性。本文将详细介绍Java Stream流的概念、用法和一些常见操作。 什么是Stream…

bootstrapv4轮播图去除两侧阴影及线框的方法

文章目录 前言一、前提条件&#xff1a;二、bootstrap文档组件展示与实际应用1.官方文档展示如下&#xff1a;没有阴影2.实际应用情况如下&#xff1a; 三、解决方案 前言 这篇文章主要介绍了bootstrapv4轮播图去除两侧阴影及线框的方法,本文通过示例代码给大家介绍的非常详细…

基于微信小程序的项目申报管理系统设计与实现(源码+lw+部署文档+讲解等)

文章目录 前言用户微信端的主要功能有&#xff1a;管理员的主要功能有&#xff1a;具体实现截图论文参考详细视频演示为什么选择我自己的网站自己的小程序&#xff08;小蔡coding&#xff09;有保障的售后福利 代码参考源码获取 前言 &#x1f497;博主介绍&#xff1a;✌全网粉…

【Vue】vue-cli一站式搭建SPA项目

&#x1f389;&#x1f389;欢迎来到我的CSDN主页&#xff01;&#x1f389;&#x1f389; &#x1f3c5;我是Java方文山&#xff0c;一个在CSDN分享笔记的博主。&#x1f4da;&#x1f4da; &#x1f31f;推荐给大家我的专栏《Vue快速入门》。&#x1f3af;&#x1f3af; &…

vtk- 数据类型(一) 三角链实例代码

三角链实例代码 #include <iostream> #include <string> #include <regex> #include "tuex.h" #include "vtkCylinderSource.h" #include "vtkPolyDataMapper.h" #include "vtkActor.h" #include "vtkRendere…

Java --- MySQL8数据库优化性能查看工具

目录 一、数据库服务器优化步骤 ​编辑二、查看系统性能的参数 三、统计SQL的查询成本&#xff1a;last_query_cost 四、定位执行慢的SQL&#xff1a;慢日志查询 4.1、开启并设置慢查询日志查询参数 4.2、查看慢查询数目 4.3、慢查询日志分析工具&#xff1a;mysqldumps…

MySQL单表查询和多表查询

一、单表查询 素材&#xff1a; 表名&#xff1a;worker-- 表中字段均为中文&#xff0c;比如 部门号 工资 职工号 参加工作等 CREATE TABLE worker (部门号 int(11) NOT NULL,职工号 int(11) NOT NULL,工作时间 date NOT NULL,工资 float(8,2) NOT NULL,政治面貌 varchar(10)…

帆软FineReport决策报表之页面布局

最近在用帆软决策报表绘制首页大屏&#xff0c;记录使用过程&#xff0c;方便查看。 版本&#xff1a;FineReport10.0 第一步、页面布局 页面布局其实就是组件的排列组合&#xff0c;决策报表主区域body有两种布局方式&#xff1a;自适应布局和绝对布局。 1&#xff09;自适应…

C#中实现单元测试的示例流程_MSTest测试项目

一、单元测试简介 1.1、单元测试简介 在《单元测试艺术》一书中对于单元测试的定义是&#xff1a;【一个单元测试是一段代码&#xff0c;这段代码调用一个工作单元&#xff08;指&#xff1a;调用软件中的一个方法&#xff0c;这个方法执行过程中所发生的所有行为以及最后产生…

你好,python!——python基础中的基础

〇、注释 0.1 单行注释 python中用 “# ”来给某一行注释&#xff0c; 他的快捷键是 CTRL / &#xff0c;当注释内容已被注释时&#xff0c;会解除注释 0.2 多行注释 python中用 """ 注释内容 """ 来对内容进行多行注释 ""&q…

DATE和LocalDateTime在Java中有什么区别

在Java中&#xff0c;Date和LocalDateTime是两个表示日期和时间的类&#xff0c;它们有以下区别&#xff1a; 类型&#xff1a;Date是Java旧版提供的日期和时间类&#xff0c;而LocalDateTime是Java 8引入的新日期和时间API中的类。 不可变性&#xff1a;Date是可变类&#x…

Questasim与Visualizer的livesim仿真

1.前言 Live-Simulation (live-sim)模式允许Visualizer调试环境与Questasim进行交互操作&#xff0c;此模式将Visualizer GUI与Questasim仿真相结合&#xff0c;因此可以在线调试当前仿真的结果和波形。在livesim模式中&#xff0c;可以在Visualizer GUI中控制仿真、设置断点(…

【Java 基础篇】Java 类加载器详解

在Java编程中&#xff0c;类加载器&#xff08;Class Loader&#xff09;是一个重要的概念&#xff0c;它负责将类加载到Java虚拟机中&#xff0c;使程序能够正常运行。本文将详细解释Java类加载器的工作原理、不同类型的类加载器以及如何自定义类加载器。 什么是类加载器&…