下面代码简单实现了手绘画板功能,其实也是Canvas的教程,后面都给加了注释。
这里通过列表来存储笔画,实现撤销恢复功能,右键有菜单。

import tkinter as tk
from tkinter import ttkclass tkinter_example(object):def __init__(s):s.win = tk.Tk()               # 创建主窗口s.win.title("tkinter Canvas") # 窗口标题s.win.withdraw()              # 隐藏窗口s.win.update_idletasks()      # 刷新窗口s.width, s.height = 600,400   #获取此时窗口大小s.Canvas()                    # 添加Canvas界面#窗口位置居中s.win.geometry('%dx%d+%d+%d' % (s.width, s.height, (s.win.winfo_screenwidth()  - s.width)/2,(s.win.winfo_screenheight() - s.height)/2))s.win.resizable(0,0)     # 阻止GUI大小调整s.win.deiconify()        # 显示窗口s.win.mainloop()         # 显示主窗口def Canvas(s):#新建画布界面canvas = tk.Canvas(s.win, width=s.width, height=s.height, highlightthickness=0, bg='#AFEEEE')  canvas.grid()#鼠标中键滚动事件canvas.bind("<MouseWheel>", lambda event: print("向上滚动") if event.delta > 0 else print("向下滚动"))#指定tag点击事件响应canvas.tag_bind('other','<Button-1>', lambda event: print("tags='other'的点击响应"))#画一条直线提供所要绘制的直线连接的两个点坐标canvas.create_line(0, 30, s.width, 30, fill="#476042", dash = (4, 4))  #加了dash就是虚线,不加就是实线#画一个矩形,提供两个点的坐标: 第一个点为左上角坐标, 第二个点为右下角坐标, outline边框颜色,fill填充颜色canvas.create_rectangle(5, 5, 45, 25, outline="#476042", fill="#476042", tags = "other")#写文字,文字将以此坐标为中心进行绘制,也写 anchor 属性来改变文字绘制的对齐方式. 比如:anchor = 'nw'canvas.create_text(25, 15, text="Python", fill="#ffffff")#画一个椭圆,提供椭圆外切矩形两个顶点,同画矩形canvas.create_oval(50, 5, 100, 25, fill="#476042", tags = "other")#画一个正圆,提供正圆外切正方形两个顶点,同画矩形canvas.create_oval(105, 5, 125, 25, fill="#476042", tags = "other")#绘制多边形points1 = [130, 25, 160, 25, 145,  5]#三角形canvas.create_polygon(points1, outline="#ff0000", fill='#ff0000', width=1, tags = "other")#绘制图片,贴图(这里的贴图必须是 全局 或者和 mainloop在同一个函数下,否则会被清除导致不显示)s.image = tk.PhotoImage(file = tk.__file__.split("tkinter")[0] + 'test\\imghdrdata\\python.gif')canvas.create_image(180, 10, anchor = 'nw', image = s.image, tags = "other")#画弧线(坐标,start = 开始方向角,extent = 结束方向角)canvas.create_arc((200, 5, 245, 50), start = 0, extent = 120, fill = "blue", tags = "other")#绘制Bitmapbitmaps = ["error", "gray75", "gray50", "gray25", "gray12", "hourglass", "info", "questhead", "question", "warning"]nsteps = len(bitmaps)step_x = int((s.width-250) / nsteps)for i in range(0, nsteps):canvas.create_bitmap(250 + (i+1)*step_x - step_x/2,15, bitmap=bitmaps[i])#创建一个可在 canvas 上手动绘图的效果,通过两点画线段的方式draw_point = ['', '']  #用于储存拖拉鼠标时的点revoke     = [ ] #用于储存每次鼠标绘图操作的ID供撤销用[[...],[...],[...]]recover    = [ ] #用于储存每次鼠标绘图的点构成的列表供恢复clear      = [ ] #用于记录是否使用过清空,因为列表可变,支持全局修改,所以用列表记录def _canvas_draw(event):if not event: #松开鼠标左键时执行,清空记录点draw_point[:] = ['','']  #[:]只改变draw_point指向的列表的内容,不是重新赋值一个新的列表所以修改值全局通用returnpoint = [event.x, event.y]   #此次传递的点坐标if draw_point==['','']:      #按下鼠标左键开始拖动时执行draw_point[:] = point    #保存拖动的第一个点if len(revoke) < len(recover):recover[len(revoke):] = [] #用于使用过撤销后再绘图,清除撤销点后的恢复数据clear[:] = []revoke.append([])        #新建一个撤销记录列表recover.append([])       #新建一个恢复记录列表recover[-1].extend(point)#在新建的恢复记录列表里记录第一个点else:revoke[-1].append(canvas.create_line(draw_point[0], draw_point[1], event.x, event.y, fill="#476042", width=1,tags = "line"))      #绘制的线段并保存到撤销记录的末次列表draw_point[:] = point    #保存拖动点,覆盖上一次recover[-1].extend(point)#保存此次传递的点坐标到恢复记录的末次列表canvas.bind("<B1-Motion>", _canvas_draw) #设定拖动鼠标左键画线段canvas.bind("<ButtonRelease-1>", lambda event:_canvas_draw(0)) #设定松开鼠标左键清除保存的点#添加撤销和恢复功能rev撤销,rec恢复def _canvas_re(rev=0, rec=0):if rev and revoke: #撤销执行for i in revoke.pop(-1): canvas.delete(i) #pop弹出最后一个撤销列表,删除图像elif rec and recover and (len(revoke) != len(recover)): #恢复执行,恢复列表需要大于撤销列表if clear:for i in recover: revoke.append([canvas.create_line(i , fill="#476042", width=1, tags = "line")])clear[:] = []else:revoke.append([canvas.create_line(recover[len(revoke)], fill="#476042", width=1, tags = "line")])#清空功能def _canvas_clear():canvas.delete("line") #清除 tags = "line"的图像revoke[:] = []clear.append(1)#添加右键菜单menu = tk.Menu(s.win, tearoff=0)    #不加 tearoff=0 的会出现可弹出选项menu.add_command(label="撤销", command = lambda:_canvas_re(rev=1))menu.add_command(label="恢复", command = lambda:_canvas_re(rec=1))menu.add_command(label="清空", command = _canvas_clear)canvas.bind("<Button-3>", lambda event: menu.post(event.x_root,event.y_root))#右键激活菜单# 创建一个Button对象,默认设置为居中对齐bt1 = ttk.Button(canvas,text = '撤销',command = lambda:_canvas_re(rev=1))#修改button在canvas上的对齐方式canvas.create_window((5, s.height-20), window = bt1, anchor = 'w')bt2 = ttk.Button(canvas,text = '恢复',command = lambda:_canvas_re(rec=1))canvas.create_window((s.width-90, s.height-20), window = bt2, anchor = 'w')bt3 = ttk.Button(canvas,text = "清空", command = _canvas_clear)canvas.create_window((s.width/2-43, s.height-20), window = bt3, anchor = 'w')tkinter_example()

tkinter Canvas 实现 鼠标手绘画板 功能相关推荐

  1. 用BufferedImage和Graphics实现简单鼠标手绘画板(Java)

    实现效果: 1.用鼠标在画板上拖拽实现画线条: 2.右击鼠标点击指定的颜色可切换画笔颜色,再次拖拽实现画线条: 代码实现: import javax.swing.*; import java.awt. ...

  2. 少儿创意学编程(Scratch基础篇):第5课——绘画板

    <少儿创意学编程(Scratch基础篇)>,参考了英国公益组织发起的"code club(代码俱乐部)"--少儿免费学编程活动.愿为中国的少儿创意编程教育尽微薄之力,对 ...

  3. 在 iOS 中使用 OpenGL ES 实现绘画板

    作者:lyman 来源: http://www.lymanli.com/2020/01/04/ios-opengles-paint/ 今天我们使用 OpenGL ES 来实现一个绘画板,主要介绍在 O ...

  4. canvas 实现绘画板

    canvas 实现绘画板 起始:使用HTML5的canvas特性,在Vue+element项目中,结合JS实现你画我猜小游戏绘画板,也可以满足订单在确认时候签名的需求.保存了鼠标的轨迹,还有绘画圆形. ...

  5. 手把手教你实现一个canvas智绘画板

    手把手教你实现一个canvas智绘画板 下载地址 前言 本文主要介绍: 项目介绍 项目效果展示 一步步实现项目效果 踩坑 一.项目介绍 名称: 智绘画板 技术栈: HTML5,CSS3,JavaScr ...

  6. 【分享】用Canvas实现画板功能

    前言 PC端测试:QQ浏览器全屏绘画完成.缩小时内容会被清空,切换背景颜色内容会被重置,其他暂无发现: 手机端测试:微信内置浏览器不通过:Safari 浏览器使用画笔时没固定页面会有抖动效果,使用橡皮 ...

  7. 巧用canvas实现画板功能,使用画笔在图片上涂画,橡皮擦可擦除涂画,并保存

    canvas 是HTML5的元素,使用JavaScript 在网页上绘制图像. canvas 拥有多种绘制路径.矩形.圆形.字符以及添加图像的方法. 而如果想实现画笔在画板涂画画笔在图片上涂画,橡皮擦 ...

  8. canvas实现绘画板

    历时一周开发了一个简单的canvas实现的画板功能,这是在vue+elementui项目里开发的,支持画笔.橡皮擦.回退.清除.保存图片.切换颜色.设置宽度等.先看最终效果: 1.我们先创建一个can ...

  9. HTML5 使用canvas实现画板功能(画笔颜色切换、粗细调整、清除图像)

    标签定义图形,比如图表和其他图像,您必须使用脚本来绘制图形. 在画布上(Canvas)画一个红色矩形,渐变矩形,彩色矩形,和一些彩色的文字. HTML5 元素用于图形的绘制,通过脚本 (通常是Java ...

最新文章

  1. python将图像转换为8位单通道_使用Python将图片转换为单通道黑白图片
  2. Flink的异步I/O及Future和CompletableFuture
  3. 题目1131:合唱队形(最长递增子序列进阶)
  4. python提供了两种基本的数值类型_python数据分析(一) python当中的数据类型--数字和常用函数...
  5. 实用性超高的工具箱多功能微信小程序源码下载支持流量主
  6. python编程单词排序_Python:对输入的单词进行字典序排序输出
  7. 【数字图像处理】Hough变换C语言实现
  8. FPGA / IC 设计(一)
  9. Masonry 比例设置multipliedBy与dividedBy区别
  10. armbian 斐讯n1_树莓派/斐讯N1/ARMBIAN/安装HOME ASSISTANT
  11. 前端开发应收藏的各大网站
  12. day 11/6 英语词汇
  13. 计算机传输方式:串行传输/并行传输、同步传输/异步传输、单工/半双工/全双工
  14. 离散数学 08.02 格的定义
  15. 【渝粤题库】广东开放大学 高级商务办公软件应用 形成性考核
  16. 佳能EOS20D本站真机评测 下
  17. 酒店管理系统的E-R图和数据库模型图
  18. Hadoop流程---从tpch到hive
  19. STM32F4(正点原子)学习笔记(一):GPIO及其小实验
  20. 一步一步来制作CSS3 3D旋转相册

热门文章

  1. 数值最优化-KKT条件(一阶必要条件)证明总结
  2. 十大城市男人魅力新榜 [转帖]
  3. 写给想通过程序员转型为项目经理的人
  4. Unity使用Newtonsoft.Json插件实现XML与JSON数据的互转
  5. 缓和曲线与原曲线任意点坐标计算程序
  6. 黑白照片修复彩色软件免费有哪些?分享这三个实用的软件给你
  7. C++ vector去重 交集 并集
  8. 企业招聘UI设计常见面试题分享
  9. Jenkins的Windows10下载与安装
  10. go语言字符串变量初始化以及字符串拼接