用36条Python语句实现在Canvas上用拖动鼠标方法画直线、矩形和椭圆(圆)

这篇博客介绍了如何使用Python的Tkinter库在Canvas上通过鼠标拖动来绘制直线、矩形和椭圆。通过绑定不同的事件函数,实现了在鼠标按下、移动和释放时对图形的操作,包括创建、移动和调整大小。用户可以通过选择不同的绘制模式(线、矩形或椭圆)进行画图,并在停止画图时固定图形。
摘要由CSDN通过智能技术生成

本程序用36条Python语句实现在Canvas上用拖动鼠标方法画直线、矩形和椭圆(圆)这3种基本图形,是用Python实现win10的画图程序的相应功能。win10的画图程序除了能画直线、矩形和椭圆(圆)这3种基本图形,还可以画其它复杂图形,将在另一篇博文介绍实现画其它复杂图形的方法。现以画椭圆(圆)为例说明实现基本思路。首先为事件绑定事件函数如下:

cv.bind("<ButtonPress-1>",StartMove)  #绑定鼠标左键按下事件
cv.bind("<ButtonRelease-1>",StopMove) #绑定鼠标左键松开事件
cv.bind("<B1-Motion>", OnMotion)      #绑定鼠标左键被按下时移动鼠标事件

在鼠标左键按下事件函数StartMove中,首先保存点击处鼠标坐标为矩形左上角坐标,该坐标在画圆期间一直不变。然后创建一个小圆。cv是Canvas实例。注意tags=(‘L’),通过它能操作这个圆。

first_x,first_y = event.x,event.y	#(event.x,event.y)鼠标单击处坐标
cv.create_oval(event.x,event.y,event.x+2,event.y+2,tags=('L'))

在鼠标左键按下并移动事件函数OnMotion中,用Canvas方法coords移动、变形、放大或缩小这个矩形。方法coords功能是按照指定左上角和右下角坐标的矩形重画圆。请注意,是通过tags=(‘L’)重画这个圆。如tags=(‘L’)代表一个矩形,那么就重画矩形,如代表一条直线,就重画直线。换句话讲,无论在事件函数StartMove中创建的是直线、矩形或椭圆(圆),只要其tags=(‘L’),下边语句都能完成对这个图形的移动、变形、放大或缩小。

cv.coords('L',first_x,first_y,event.x,event.y)

在鼠标左键抬起事件函数StopMove中,固定图形,还必须删除tags为’L’的实例中这个为’L’的tag。因重新创建新的直线、矩形或椭圆(圆)时,还要用令tags=(‘L’),不删除就会同时操作旧的图形。

cv.coords('L',first_x,first_y,event.x,event.y)
cv.dtag('L','L')

具体代码如下:

import tkinter as tk
root = tk.Tk()
root.geometry('300x410')
cv = tk.Canvas(root, height=300, width=300,bg='silver')
cv.pack()
def StartMove(event):    
    global first_x,first_y
    if var.get()=='stop':
        return
    first_x,first_y = event.x,event.y
    if var.get()=='line':
        cv.create_line(event.x,event.y,event.x+2,event.y+2,tags=('L'))
    elif var.get()=='rectangle':
        cv.create_rectangle(event.x,event.y,event.x+2,event.y+2,tags=('L'))
    elif var.get()=='oval':
        cv.create_oval(event.x,event.y,event.x+2,event.y+2,tags=('L'))
def StopMove(event):
    global first_x,first_x
    if var.get()=='stop':
        return
    cv.coords('L',first_x,first_y,event.x,event.y)
    if ((abs(event.x-first_x)+abs(event.y-first_y))<6):#避免在窗体点一下,出一个点
        cv.delete('L')
    cv.dtag('L','L')
def OnMotion(event):
    global first_x,first_x
    if var.get()=='stop':
        return
    cv.coords('L',first_x,first_y,event.x,event.y)
var = tk.StringVar()
tk.Radiobutton(root,text = '线',variable=var,value = 'line').pack()
tk.Radiobutton(root,text = '矩形',variable=var,value = 'rectangle').pack()
tk.Radiobutton(root,text = '圆',variable=var,value = 'oval').pack()
tk.Radiobutton(root,text = '停止画图',variable=var,value = 'stop').pack()
cv.bind("<ButtonPress-1>",StartMove)  #绑定鼠标左键按下事件
cv.bind("<ButtonRelease-1>",StopMove) #绑定鼠标左键松开事件
cv.bind("<B1-Motion>", OnMotion)      #绑定鼠标左键被按下时移动鼠标事件
root.mainloop()
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值