【问题标题】:Drawing with mouse on Tkinter Canvas在 Tkinter Canvas 上用鼠标绘图
【发布时间】:2021-12-18 12:17:49
【问题描述】:

我找到了下面这段代码here

from tkinter import *

canvas_width = 500
canvas_height = 150

def 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 )
    
master.mainloop()

它允许您通过拖动鼠标在 Tkinter 画布上绘图。当我非常缓慢地移动鼠标时,它工作得很好,但是当我移动它的速度快一点时,线条就断了。这就是我的意思:

Screenshot of the Tkinter window

上面的线画得很慢。 底部的那个,相当快。 如您所见,底部的许多地方都缺少点。我该如何解决这个问题?

【问题讨论】:

    标签: python-3.x tkinter


    【解决方案1】:

    如果你想画一条线,你需要注册鼠标移动的坐标,并使用create_line方法根据该坐标创建线,因为它连接了这些点。因此,将鼠标的位置附加到列表中并绘制一条线并使用该列表中的坐标。当您开始绘图时(单击鼠标),附加起始坐标。然后在移动时附加坐标,删除前一行(基本上是更新)并绘制一个新的。释放鼠标按钮时,清除点列表并将当前线 id 设置为 None 以指示当前没有绘制线。

    import tkinter as tk
    
    line_id = None
    line_points = []
    line_options = {}
    
    
    def draw_line(event):
        global line_id
        line_points.extend((event.x, event.y))
        if line_id is not None:
            canvas.delete(line_id)
        line_id = canvas.create_line(line_points, **line_options)
    
    
    def set_start(event):
        line_points.extend((event.x, event.y))
    
    
    def end_line(event=None):
        global line_id
        line_points.clear()
        line_id = None
    
    
    root = tk.Tk()
    
    canvas = tk.Canvas()
    canvas.pack()
    
    canvas.bind('<Button-1>', set_start)
    canvas.bind('<B1-Motion>', draw_line)
    canvas.bind('<ButtonRelease-1>', end_line)
    
    root.mainloop()
    

    还有:
    我强烈建议在导入某些内容时不要使用通配符 (*),您应该导入您需要的内容,例如from module import Class1, func_1, var_2 等等或导入整个模块:import module 然后你也可以使用别名:import module as md 或类似的东西,关键是不要导入所有东西,除非你真的知道你在做什么;名称冲突是问题所在。

    【讨论】:

    • 谢谢,用 create_line() 连接点就可以了!但是为什么画椭圆不起作用呢?我的意思是,由于鼠标在我想要一条线的区域上移动,不应该在鼠标经过的任何地方绘制椭圆产生与您的代码相同的结果吗?
    • @1d10t tkinter 可能不会记录鼠标的每个位置,所以你走得越快,它所记录的两点之间的距离就越大。画线时,只需要计算两点之间的像素并改变它们的颜色(所以不管两点有多远,它都会在它们之间画一条线)。此外,让它不记录鼠标经过的每个像素也很有用,因为有时您想确定用户移动鼠标的速度并提高性能(tkinter 有点慢)
    猜你喜欢
    • 2011-01-23
    • 1970-01-01
    • 1970-01-01
    • 2015-06-29
    • 1970-01-01
    • 1970-01-01
    • 2012-11-14
    • 2014-09-04
    • 1970-01-01
    相关资源
    最近更新 更多