[Tkinter 教程08] Canvas 图形绘制
python - [译][Tkinter 教程08] Canvas 图形绘制 - 个人文章 - SegmentFault 思否
一、简介
Canvas 为 Tkinter 提供了绘图功能. 其提供的图形组件包括 线形, 圆形, 图片, 甚至其他控件. Canvas 控件为绘制图形图表, 编辑图形, 自定义控件提供了可能.
在第一个例子里, 我们将演示如何画一条直线. create_line(coords, options)
方法用来绘制一条直线. coords
为以整形表示的四个坐标参数: x1, y1, x2, y2 . 这表示所要绘制的直线连接了 (x1, y1) 和 (x2, y2) 这两个点. 除坐标外, 该方法还接受其他可选的 options
参数. 在下面的例子里我们用 options
参数指定颜色为我们网站的主题色: fill=#476042
.
因为是第一个例子, 所以我们尽量做了简化: 创建一个 canvas 对象然后在其上绘制一条水平直线. 这条直线将 canvas 分割为上下两部分.
在传入坐标参数时, y = int(canvas_height / 2)
这种强制转换整形的表达式是没有必要的, 因为 create_line()
方法也接受 float 类型作为坐标参数, float 坐标数值将被自动转为整形. 下面是第一个例子的代码:
from tkinter import * master = Tk()canvas_width = 80 canvas_height = 40 w = Canvas(master, width=canvas_width,height=canvas_height) w.pack()y = int(canvas_height / 2) w.create_line(0, y, canvas_width, y, fill="#476042")mainloop()
上述代码在 Python3 下会有如下显示:
使用 create_rectangle(coords, options)
方法可以绘制矩形. coords
参数依然表示两个点的坐标: 第一个点为左上角坐标, 第二个点为右下角坐标.
上面的窗口是由以下示例代码生成的:
from tkinter import *master = Tk()w = Canvas(master, width=200, height=100) w.pack()w.create_rectangle(50, 20, 150, 80, fill="#476042") w.create_rectangle(65, 35, 135, 65, fill="yellow") w.create_line(0, 0, 50, 20, fill="#476042", width=3) w.create_line(0, 100, 50, 80, fill="#476042", width=3) w.create_line(150,20, 200, 0, fill="#476042", width=3) w.create_line(150, 80, 200, 100, fill="#476042", width=3)mainloop()
下图阐释了上面两个例子中 create_lines()
和 create_rectangle()
这两个方法中, 用到的各个坐标的含义:
二、绘制文字
接下来我们将说明如何在 canvas 上绘制文字. 我们将直接修改上面的例子以作为新的示例. create_text()
方法用来在 canvas 上绘制文字. 该方法的头两个参数表示所要绘制的文字的坐标. 默认情况下, 文字将以此坐标为中心进行绘制. 当然, 你也可以复写 anchor 属性来改变文字绘制的对齐方式. 比如, anchor = NW
即为指定该点坐标为所绘文字的左上角. text 属性用以指定具体绘制在 canvas 上的文字.
from tkinter import *canvas_width = 200 canvas_height = 100colours = ("#476042", "yellow") box=[]for ratio in ( 0.2, 0.35 ):box.append( (canvas_width * ratio,canvas_height * ratio,canvas_width * (1 - ratio),canvas_height * (1 - ratio) ) )master = Tk()w = Canvas(master, width=canvas_width, height=canvas_height) w.pack()for i in range(2):w.create_rectangle(box[i][0], box[i][1],box[i][2],box[i][3], fill=colours[i])w.create_line(0, 0, # canvas 原点box[0][0], box[0][1], # box[0] 的左上角坐标fill=colours[0], width=3) w.create_line(0, canvas_height, # canvas 的左下角坐标box[0][0], box[0][3], # box[0] 的左下角坐标fill=colours[0], width=3) w.create_line(box[0][2],box[0][1], # box[0] 的右上角坐标canvas_width, 0, # canvas 的右上角坐标fill=colours[0], width=3) w.create_line(box[0][2], box[0][3], # box[0] 的右下角坐标canvas_width, canvas_height, # canvas 的右下角坐标fill=colours[0], width=3)w.create_text(canvas_width / 2,canvas_height / 2,text="Python") mainloop()
虽然从代码上来看, 我们对之前的例子做了很大的改动, 但其所输出的结果却与前例相差不大, 仅仅在窗口的中间多了一个显示 "Python" 字样的方框:
本例中我们改用变量存储坐标等参数, 这使得改动变的方便. 比如, 要将整个画布的宽高设为 90 * 190, 将 box[0] 的宽高比设为 0.3, 在本例中将很容易做到, 但在之前的例子中却要修改很多代码.
本例运行后显示如下窗口:
三、绘制 Oval
图形 oval 是一个蛋形的曲线. 它形似椭圆, 但并不是椭圆. 事实上, oval 这个概念没有太明确的定义. 很多不同的曲线都被叫做 oval, 他们都有如下共同点:
- 都是可微分的简单 (非自相交) 凸闭曲线
- 他们比椭圆曲线简单
- 至少有一条对称轴
oval 这个词源自拉丁语中的 ovum, 意为 "蛋", 这很好的描述了它: 一条描述蛋形状的曲线. 一个 oval 由两条半径不同的弧线组成. 下图是一个特殊的 oval:
我们可以使用如下方法在 canvas 中创建一个 oval:
id = C.create_oval ( x0, y0, x1, y1, option, ... )
该方法的返回值为所创建的 oval 对象在当前 canvas 上的 ID.
下面的代码绘制了一个圆心在 (75, 75), 半径为 25 的正圆形:
from tkinter import *
canvas_width = 190
canvas_height =150
master = Tk()
w = Canvas(master, width=canvas_width, height=canvas_height)
w.pack()w.create_oval(50,50,100,100)
mainloop()
我们可以定义一个专门用来画正圆形的方法:
def circle(canvas, x, y, r):id = canvas.create_oval(x-r, y-r, x+r, y+r)return id
四、交互式绘图
我们想要创建一个可在 canvas 上手动绘图的应用, 但 canvas 并未提供画单个点的方法. 我们可以通过绘制小的 oval 图形来解决这个问题:
from tkinter import *canvas_width = 500
canvas_height = 150def paint( event ):python_green = "#476042"x1, y1 = ( event.x - 1 ), ( event.y - 1 )x2, y2 = ( event.x + 1 ), ( event.y + 1 )w.create_oval( x1, y1, x2, y2, fill = python_green )master = Tk()
master.title( "Painting using Ovals" )
w = Canvas(master, width=canvas_width, height=canvas_height)
w.pack(expand = YES, fill = BOTH)
w.bind( "<B1-Motion>", paint )message = Label( master, text = "Press and Drag the mouse to draw" )
message.pack( side = BOTTOM )
mainloop()
五、绘制多边形
如果要绘制一个多边形, 可以使用 create_polygon(x0, y0, x1, y1, x2, y2, ...)
方法. 至少要传入三个点的坐标才可以绘制一个多边形.
下例用该方法绘制了一个三角形:
from tkinter import *canvas_width = 200
canvas_height =200
python_green = "#476042"master = Tk()
w = Canvas(master, width=canvas_width,height=canvas_height)
w.pack()points = [0,0,canvas_width,canvas_height/2, 0, canvas_height]
w.create_polygon(points, outline=python_green,fill='yellow', width=3)
mainloop()
运行后显示为如下窗口:
或许你在读到这篇教程时圣诞节 马上就到了/为时尚早. 这里我们用 Python 和 Tkinter 做一些星星来装点我们的圣诞树. 第一课星星几乎没有用到任何编程技巧:
from tkinter import *canvas_width = 200 canvas_height =200 python_green = "#476042"master = Tk()w = Canvas(master, width=canvas_width, height=canvas_height) w.pack()points = [100, 140, 110, 110, 140, 100, 110, 90, 100, 60, 90, 90, 60, 100, 90, 110]w.create_polygon(points, outline=python_green, fill='yellow', width=3)mainloop()
上例非常没有技术含量. 如果我们要改变星星的大小或胖瘦, 该怎么办? 上例中我们只能重新指定所有点的坐标, 这种做法乏味且易出错. 因此, 我们用了更多的编程技巧改造了上例. 首先, 我们将星星的绘制放在一个方法体中, 并用星星的原点及两个长度指定星星的具体形状:
经过改造的代码如下:
from tkinter import *canvas_width = 400 canvas_height =400 python_green = "#476042"def polygon_star(canvas, x,y,p,t, outline=python_green, fill='yellow', width = 1):points = []for i in (1,-1):points.extend((x, y + i*p))points.extend((x + i*t, y + i*t))points.extend((x + i*p, y))points.extend((x + i*t, y - i * t))print(points)canvas.create_polygon(points, outline=outline, fill=fill, width=width)master = Tk()w = Canvas(master, width=canvas_width, height=canvas_height) w.pack()p = 50 t = 15nsteps = 10 step_x = int(canvas_width / nsteps) step_y = int(canvas_height / nsteps)for i in range(1, nsteps):polygon_star(w,i*step_x,i*step_y,p,t,outline='red',fill='gold', width=3)polygon_star(w,i*step_x,canvas_height - i*step_y,p,t,outline='red',fill='gold', width=3)mainloop()
这个例子的运行结果更像一个X形. 很显然, 用逐个指定坐标点的方法绘制这个图形将无比麻烦.
六、绘制Bitmap
create_bitmap()
方法用来绘制 bitmap. 以下 bitmap 在所有平台上都可用:
"error", "gray75", "gray50", "gray25", "gray12", "hourglass", "info", "questhead", "question", "warning"
下例将这些 bitmap 全部都绘制在一个 canvas 上:
from tkinter import *canvas_width = 300 canvas_height =80master = Tk() canvas = Canvas(master, width=canvas_width, height=canvas_height) canvas.pack()bitmaps = ["error", "gray75", "gray50", "gray25", "gray12", "hourglass", "info", "questhead", "question", "warning"] nsteps = len(bitmaps) step_x = int(canvas_width / nsteps)for i in range(0, nsteps):canvas.create_bitmap((i+1)*step_x - step_x/2,50, bitmap=bitmaps[i])mainloop()
结果如下:
七、绘制图片
使用 create_image(x0, x0, options ...)
用来在 canvas 上绘制图片. 该方法不能直接接受图片路径等作为参数, 而是接受一个 PhotoImage 对象作为图片参数. PhotoImage 类用于读取图片, 但其只能读取 GIF 和 PGM/PPM 格式的图片.
from tkinter import *canvas_width = 300 canvas_height =300master = Tk()canvas = Canvas(master, width=canvas_width, height=canvas_height) canvas.pack()img = PhotoImage(file="rocks.ppm") canvas.create_image(20,20, anchor=NW, image=img)mainloop()
上面的代码运行后输出如下窗口:
八、小练习
编写一个方法绘制一个棋盘: checkered(canvas, line_distance)
, 其中: "canvas" 即 Canvas 对象, 棋盘在其上绘制; "line_distance" 为线间距.
代码如下:
from tkinter import *def checkered(canvas, line_distance):# vertical lines at an interval of "line_distance" pixelfor x in range(line_distance,canvas_width,line_distance):canvas.create_line(x, 0, x, canvas_height, fill="#476042")# horizontal lines at an interval of "line_distance" pixelfor y in range(line_distance,canvas_height,line_distance):canvas.create_line(0, y, canvas_width, y, fill="#476042")master = Tk() canvas_width = 200 canvas_height = 100 w = Canvas(master, width=canvas_width,height=canvas_height) w.pack()checkered(w,10)mainloop()
上面的代码运行后输出如下窗口:
全系列:
相关文章:

[Tkinter 教程08] Canvas 图形绘制
python - [译][Tkinter 教程08] Canvas 图形绘制 - 个人文章 - SegmentFault 思否 一、简介 Canvas 为 Tkinter 提供了绘图功能. 其提供的图形组件包括 线形, 圆形, 图片, 甚至其他控件. Canvas 控件为绘制图形图表, 编辑图形, 自定义控件提供了可能. 在第一个例子里, …...

ES6 Symbol 数据结构
1. Symbol概念以及引入原因 ES6 引入了的一种新的原始数据类型Symbol,表示独一无二的值。它是 JavaScript 语言的第七种数据类型,前六种是:undefined、null、布尔值(Boolean)、字符串(String)、…...

Redis常用数据类型、Redis常用命令
Redis常用数据类型、Redis常用命令: Redis常用数据类型:1. 字符串String 类型2. 哈希hash 类型3. 列表list 类型4. 集合set 类型5. 有序集合sorted set / zset 类型 Redis常用命令:1. 字符串操作命令2. 哈希操作命令3. 列表操作命令4. 集合操…...

ERP系统是如何运作的?erp管理系统操作流程
ERP系统是如何运作的?ERP系统的运作流程是怎样的? 以简道云ERP管理系统为例: 各行各业适配的ERP系统>>>>https://www.jiandaoyun.com 可以看到上面那个流程图,一般来说,我们把ERP系统可以分为4个大的模…...

springBoot复杂对象表示和lombok的使用
springBoot复杂对象表示 前言简单案例lombok的使用通过properties文件进行绑定在yaml文件中使用 前言 对象:键值对的集合,如:映射(map)/哈希(hash)/字典(dictionary) 数组:一组按次…...

如何选择最适合你的LLM优化方法:全面微调、PEFT、提示工程和RAG对比分析
一、前言 自从ChatGPT问世以来,全球各地的企业都迫切希望利用大型语言模型(LLMs)来提升他们的产品和运营。虽然LLMs具有巨大的潜力,但存在一个问题:即使是最强大的预训练LLM也可能无法直接满足你的特定需求。其原因如…...
Jenkins实现CI/CD发布(Ansible/jenkins共享库/gitlab)
Jenkins实现多环境发布 1. 需求介绍 本人负责公司前端业务模块,由于前端模块较多,所以在编写jenkinsfile时会出现很多项目使用的大部分代码相同的情况,为解决这种问题,采用了jenkins的共享库方式优化,并且jenkins要支持…...

使用navicat查看类型颜色
问题描述: 最近遇到一个mongodb的数据问题。 在date日期数据中,混入了string类型的数据,导致查询视图报错: $add only supports numeric or date types解决办法: 使用类型颜色工具。 找到在last_modified_date字段中…...
iOS 中,Atomic 修饰 NSString、 NSArray,也会线程不安全
众所周知,基础类型如 int、float 的变量被 atomic 修饰后就具有原子性,则线程安全。 然而有些情况,atomic 修饰后不一定是线程安全的。 atomic 修饰 NSString,NSArray 的时候,只是保障首地址(数组名&…...

2023医药微信公众号排名榜top100汇总合集
相信每个医药人都或多或少关注了几个医药微信公众号,便于日常了解到最新的医药新闻包括治疗技术、药物研发、研究成果、医学进展、临床试验进展、市场动向等前沿动态。 笔者也不列外,大大小小的公众号收集了有上百个,本着方便查看的目的&…...

基于YOLO算法的单目相机2D测量(工件尺寸和物体尺寸)三
1.简介 1.1 2D测量技术 基于单目相机的2D测量技术在许多领域中具有重要的背景和意义。 工业制造:在工业制造过程中,精确测量是确保产品质量和一致性的关键。基于单目相机的2D测量技术可以用于检测和测量零件尺寸、位置、形状等参数,进而实…...
Cython编译文件出错
报错信息: (rpc) stuamax:~/segment/dss_crf$ python setup.py install Compiling pydensecrf/eigen.pyx because it changed. Compiling pydensecrf/densecrf.pyx because it changed. [1/2] Cythonizing pydensecrf/densecrf.pyx /home/stu/anaconda3/envs/rpc/l…...

WPF 用户控件依赖注入赋值
前言 我一直想组件化得去开发WPF,因为我觉得将复杂问题简单化是最好的 如何组件化开发 主窗口引用 <Window x:Class"WpfApp1.MainWindow"xmlns"http://schemas.microsoft.com/winfx/2006/xaml/presentation"xmlns:x"http://schemas.…...

leetcode-48.旋转图像
1. 题目 leetcode题目链接 给定一个 n n 的二维矩阵 matrix 表示一个图像。请你将图像顺时针旋转 90 度。 你必须在 原地 旋转图像,这意味着你需要直接修改输入的二维矩阵。请不要 使用另一个矩阵来旋转图像。 2. 编程 矩阵转置: 遍历矩阵&#x…...

antd的RangePicker设置默认值,默认近七天(andt+react)
import moment from "moment";state {initData:[moment().startOf(day).subtract(6, d), moment().endOf(day)], }<FormItem label"产生时间" {...tailItemLayout}>{getFieldDecorator("produceTime", {initialValue: initData})(<Ran…...

大数据可视化模块竞赛Vue项目文件结构与注意事项
1.vue项目src目录下只有两个文件夹与两个js文件,如图所示: 2.asseets目录存放包或其他外部资料 注意 :echarts采用的是引用外部文件导入 let echarts = require(@/assets/echarts.min.js) 3.components目录存放绘制页面的vue文件(我这里示例创建了一个newPage.vue)…...

户外运动盛行,运动品牌如何利用软文推广脱颖而出?
全民健康意识的提升和城市居民对亲近自然的渴望带来户外运动的盛行,这也使运动品牌的市场保持强劲发展势头,那么在激烈的市场竞争中,运动品牌应该如何脱颖而出呢?下面就让媒介盒子告诉你! 一、 分享户外运动干货 用户…...

2024年孝感市建筑类中级职称申报资料私企VS国企
2024年孝感市建筑类中级职称申报资料私企VS国企 民营企业中级职称申报跟事业单位或者是国企申报中级职称流程不一样么?实际上流程基本都是相同的,就是提交纸质版资料有点不一样。 孝感市建筑类中级职称申报基本流程 1.参加建筑类中级职称水平能力测试。 …...

OpenResty安装
OpenResty 是一个基于 Nginx 的 Web 平台,它将 Nginx 和 Lua 脚本语言结合起来,提供了更强大的 Web 应用开发和部署能力。OpenResty 仓库是 OpenResty 项目的官方仓库,包含了 OpenResty 的源代码、文档、示例等资源。 OpenResty 仓库地址是&…...

通过stream对list集合中对象的多个字段进行去重
记录下通过stream流对list集合中对象的多个字段进行去重! 举个栗子,对象book,我们要通过姓名和价格这两个字段的值进行去重,该这么做呢? distinct()返回由该流的不同元素组成的流。distinct&am…...

多云管理“拦路虎”:深入解析网络互联、身份同步与成本可视化的技术复杂度
一、引言:多云环境的技术复杂性本质 企业采用多云策略已从技术选型升维至生存刚需。当业务系统分散部署在多个云平台时,基础设施的技术债呈现指数级积累。网络连接、身份认证、成本管理这三大核心挑战相互嵌套:跨云网络构建数据…...

智慧工地云平台源码,基于微服务架构+Java+Spring Cloud +UniApp +MySql
智慧工地管理云平台系统,智慧工地全套源码,java版智慧工地源码,支持PC端、大屏端、移动端。 智慧工地聚焦建筑行业的市场需求,提供“平台网络终端”的整体解决方案,提供劳务管理、视频管理、智能监测、绿色施工、安全管…...
JVM垃圾回收机制全解析
Java虚拟机(JVM)中的垃圾收集器(Garbage Collector,简称GC)是用于自动管理内存的机制。它负责识别和清除不再被程序使用的对象,从而释放内存空间,避免内存泄漏和内存溢出等问题。垃圾收集器在Ja…...

江苏艾立泰跨国资源接力:废料变黄金的绿色供应链革命
在华东塑料包装行业面临限塑令深度调整的背景下,江苏艾立泰以一场跨国资源接力的创新实践,重新定义了绿色供应链的边界。 跨国回收网络:废料变黄金的全球棋局 艾立泰在欧洲、东南亚建立再生塑料回收点,将海外废弃包装箱通过标准…...
论文解读:交大港大上海AI Lab开源论文 | 宇树机器人多姿态起立控制强化学习框架(一)
宇树机器人多姿态起立控制强化学习框架论文解析 论文解读:交大&港大&上海AI Lab开源论文 | 宇树机器人多姿态起立控制强化学习框架(一) 论文解读:交大&港大&上海AI Lab开源论文 | 宇树机器人多姿态起立控制强化…...
【RockeMQ】第2节|RocketMQ快速实战以及核⼼概念详解(二)
升级Dledger高可用集群 一、主从架构的不足与Dledger的定位 主从架构缺陷 数据备份依赖Slave节点,但无自动故障转移能力,Master宕机后需人工切换,期间消息可能无法读取。Slave仅存储数据,无法主动升级为Master响应请求ÿ…...
CRMEB 框架中 PHP 上传扩展开发:涵盖本地上传及阿里云 OSS、腾讯云 COS、七牛云
目前已有本地上传、阿里云OSS上传、腾讯云COS上传、七牛云上传扩展 扩展入口文件 文件目录 crmeb\services\upload\Upload.php namespace crmeb\services\upload;use crmeb\basic\BaseManager; use think\facade\Config;/*** Class Upload* package crmeb\services\upload* …...

使用 SymPy 进行向量和矩阵的高级操作
在科学计算和工程领域,向量和矩阵操作是解决问题的核心技能之一。Python 的 SymPy 库提供了强大的符号计算功能,能够高效地处理向量和矩阵的各种操作。本文将深入探讨如何使用 SymPy 进行向量和矩阵的创建、合并以及维度拓展等操作,并通过具体…...

处理vxe-table 表尾数据是单独一个接口,表格tableData数据更新后,需要点击两下,表尾才是正确的
修改bug思路: 分别把 tabledata 和 表尾相关数据 console.log() 发现 更新数据先后顺序不对 settimeout延迟查询表格接口 ——测试可行 升级↑:async await 等接口返回后再开始下一个接口查询 ________________________________________________________…...
scikit-learn机器学习
# 同时添加如下代码, 这样每次环境(kernel)启动的时候只要运行下方代码即可: # Also add the following code, # so that every time the environment (kernel) starts, # just run the following code: import sys sys.path.append(/home/aistudio/external-libraries)机…...