【Tkinter界面】Canvas 图形绘制(03/5)

文章目录

https://www.cnblogs.com/rainbow-tan/p/14852553.html

一、说明

Canvas(画布)组件为 Tkinter 的图形绘制提供了基础。Canvas 是一个高度灵活的组件,你可以用它绘制图形和图表,创建图形编辑器,并实现各种自定义的小部件。

二、画布和画布对象

2.1 画布坐标系

由于画布可能比窗口大(带有滚动条的 Canvas 组件),因此 Canvas 组件可以选择使用两种坐标系:

  • 窗口坐标系:以窗口的左上角作为坐标原点
  • 画布坐标系:以画布的左上角作为坐标原点
    将窗口坐标系转换为画布坐标系,可以使用 canvasx() 或 canvasy() 方法:
python 复制代码
def callback(event):
    canvas = event.widget
    x = canvas.canvasx(event.x)
    y = canvas.canvasy(event.y)
    print canvas.find_closest(x, y)

2.2 鼠标点中画布位置

python 复制代码
import tkinter as tk
root = tk.Tk()
w = tk.Canvas(root, width=400, height=400)
w.pack()

def Do_But():
# 查看所有画布对象的ID
    ss = w.find_all()
    for i in ss:
        coords = w.coords(i)
        print(i,coords)

def paint(event):
    x1, y1 = (event.x - 1), (event.y - 1)
    x2, y2 = (event.x + 1), (event.y + 1)
    s=w.create_oval(x1, y1, x2, y2, fill="black")
    print(s)


w.bind("<B1-Motion>", paint)

tk.Label(root, text="按住鼠标左键并移动,开始绘制你的理想蓝图吧......").pack(side="bottom")
tk.Button(root, text="正圆", width=10, height=1, command=Do_But).pack(side="left")
root.mainloop()

2.3 画布对象显示的顺序

Canvas 组件中创建的画布对象都会被列入显示列表中,越接近背景的画布对象位于显示列表的越下方。显示列表决定当两个画布对象重叠的时候是如何覆盖的(默认情况下新创建的会覆盖旧的画布对象的重叠部分,即位于显示列表上方的画布对象将覆盖下方那个)。当然,显示列表中的画布对象可以被重新排序。

2.4 指定画布对象

Canvas 组件提供几种方法让你指定画布对象:

  • Item handles
  • Tags
  • "all"
  • "current"

1)Item handles

当你在 Canvas 组件上创建一个画布对象的时候,Tkinter 将自动为其指定一个在该 Canvas 组件中独一无二的整型值。然后各种 Canvas 的方法可以通过这个值操纵该画布对象。

2)Tags

是附在画布对象上的标签,Tags 由普通的非空白字符串组成。一个画布对象可以与多个 Tags 相关联,一个 Tag 也可用于描述多个画布对象。然而,与 Text 组件不同,没有指定画布对象的 Tags 不能进行事件绑定和配置样式。也就是说,Canvas 组件的 Tags 是仅为画布对象所拥有。

Canvas 组件预定义了两个 Tags:"all" 和 "current"

3) "all"

表示 Canvas 组件中的所有画布对象
4)"current"

"current" 表示鼠标指针下的画布对象(如果有的话)

三、你应该知道的画布对象操作

3.1 什么是Tag

Tag是个签,可以对画布对象指定,画布对象对象可以:没有标签、拥有多个标签。

标签的意义,在于对同类对象进行标签分类。

tags的说明

Tags 是附在画布对象上的标签,Tags 由普通的非空白字符串组成。一个画布对象可以与多个 Tags 相关联,一个 Tag 也可用于描述多个画布对象。

Canvas 组件预定义了两个 Tags:"all" 和 "current"

"all" 表示 Canvas 组件中的所有画布对象

"current" 表示鼠标指针下的画布对象(如果有的话)

3.2 操作Tag的函数

  • *addtag(tag, method, args)

    -- 添加一个 Tag 到一系列画布对象中

    -- 指定添加 Tag 的位置,可以是:"above","all","below","closest","enclosed","overlapping" 或 "withtag"

    -- args 是附加参数,请参考下方等同的方法

  • addtag_above(tag, item)

    -- 为显示列表中 item 上方的画布对象添加 Tag

    -- 该方法相当于 addtag(tag, "above", item)

    -- item 可以是单个画布对象的 ID,也可以是某个 Tag

  • addtag_all(tag)

    -- 为 Canvas 组件中所有的画布对象添加 Tag

    -- 该方法相当于 addtag(tag, "all")

  • addtag_below(tag, item)

    -- 为显示列表中 item 下方的画布对象添加 Tag

    -- 该方法相当于 addtag(tag, "below", item)

    -- item 可以是单个画布对象的 ID,也可以是某个 Tag

  • addtag_closest(tag, x, y, halo=None, start=None)

    -- 将 Tag 添加到与给定坐标(x, y)相临近的画布对象

    -- 可选参数 halo 指定一个距离,表示以(x, y)为中心,该距离内的所有画布对象均添加 Tag

    -- 可选参数 start 指定一个画布对象,该方法将为低于但最接近该对象的画布对象添加 Tag

    -- 该方法相当于 addtag(tag, "closet", x, y, halo=None, start=None)

    -- 注1:使用的是画布坐标系

    -- 注2:如果同时由几个画布对象与给定坐标(x, y)的距离相同,则为位于显示列表上方的那个画布对象添加 Tag

  • addtag_enclosed(tag, x1, y1, x2, y2)

    -- 为所有坐标在矩形(x1, y1, x2, y2)中的画布对象添加 Tag

    -- 该方法相当于 addtag(tag, "enclosed", x1, y1, x2, y2)

  • addtag_overlapped(tag, x1, y1, x2, y2)

    -- 跟 addtag_enclosed() 方法相似,不过该方法范围更广(即使画布对象只有一部分在矩形中也算)

    -- 该方法相当于 addtag(tag, "overlapping", x1, y1, x2, y2)

  • addtag_withtag(tag, item)

    -- 为 item 参数指定的画布对象添加 Tag

    -- item 参数如果指定一个 Tag,则为所有拥有此 Tag 的画布对象添加新的 Tag

    -- item 参数如果指定一个画布对象,那么只为其添加 Tag

    -- 该方法相当于 addtag(tag, "withtag", item)

    -- item 可以是单个画布对象的 ID,也可以是某个 Tag

  • *bbox(args)

    -- 返回一个四元组(x1, y1, x2, y2)用于描述 args 指定的画布对象所在的矩形范围

    -- 如果 args 参数忽略,返回所有的画布对象所在的矩形范围

  • canvasx(screenx, gridspacing=None)

    -- 将窗口坐标系的 X 坐标(screenx)转化为画布坐标系

    -- 如果提供 gridspacing 参数,则转换结果将为该参数的整数倍

  • canvasy(screeny, gridspacing=None)

    -- 将窗口坐标系的 Y 坐标(screenx)转化为画布坐标系

    -- 如果提供 gridspacing 参数,则转换结果将为该参数的整数倍

  • *coords(args)

    -- 如果仅提供一个参数(画布对象),返回该画布对象的坐标 (x1, y1, x2, y2)

    -- 你可以通过 coords(item, x1, y1, x2, y2) 来移动画布对象

相关推荐
zmd-zk4 分钟前
flink学习(2)——wordcount案例
大数据·开发语言·学习·flink
好奇的菜鸟8 分钟前
Go语言中的引用类型:指针与传递机制
开发语言·后端·golang
Alive~o.017 分钟前
Go语言进阶&依赖管理
开发语言·后端·golang
花海少爷20 分钟前
第十章 JavaScript的应用课后习题
开发语言·javascript·ecmascript
手握风云-20 分钟前
数据结构(Java版)第二期:包装类和泛型
java·开发语言·数据结构
喵叔哟40 分钟前
重构代码中引入外部方法和引入本地扩展的区别
java·开发语言·重构
尘浮生1 小时前
Java项目实战II基于微信小程序的电影院买票选座系统(开发文档+数据库+源码)
java·开发语言·数据库·微信小程序·小程序·maven·intellij-idea
hopetomorrow1 小时前
学习路之PHP--使用GROUP BY 发生错误 SELECT list is not in GROUP BY clause .......... 解决
开发语言·学习·php
小牛itbull1 小时前
ReactPress vs VuePress vs WordPress
开发语言·javascript·reactpress
请叫我欧皇i1 小时前
html本地离线引入vant和vue2(详细步骤)
开发语言·前端·javascript