I found the following piece of code 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()
It lets you draw on a Tkinter canvas by dragging your mouse around. It works just fine when I move my mouse very very slowly but the moment I move it a bit faster, the lines end up broken. Here's what I mean:
Screenshot of the Tkinter window
The line on the top was drawn slowly. The one on the bottom, rather quickly. As you can see, the bottom one is missing points in many places. How do I fix this?
CodePudding user response:
If you want to draw a line, you need to register the coordinates of where the mouse moves and create line based on that using create_line
method because it connects those points. So append positions of mouse to a list and draw a line and use the coordinates from that list. When you start drawing (click mouse), append the starting coordinates. Then on movement append the coordinates, delete the previous line (basically updating) and draw a new one. When mouse button is released clear the list of points and set the current line id to None to indicate that currently no line is drawn.
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()
Also:
I strongly advise against using wildcard (*
) when importing something, You should either import what You need, e.g. from module import Class1, func_1, var_2
and so on or import the whole module: import module
then You can also use an alias: import module as md
or sth like that, the point is that don't import everything unless You actually know what You are doing; name clashes are the issue.