I'm pretty new to Python and I'm currently playing a bit with Tkinter which looks amazingly simple. I've tried to implement a simple drag and drop effect using the following code (right mouse button creates a circle, left mouse button allows dragging) :
from tkinter import *
class Point:
def __init__(self, ref, x, y):
self.ref = ref
self.x = x
self.y = y
points = []
selected = None
def OnSelect(event):
global selected
for p in points:
if event.x>=(p.x-10) and event.y>=(p.y-10) and event.x<(p.x+10) and event.y<(p.y+10):
selected = p
break
def OnMMove(event):
if selected is not None:
selected.x = event.x
selected.y = event.y
canvas.coords(selected.ref, event.x-10, event.y-10, event.x+10, event.y+10)
def OnStopDrag(event):
global selected
selected = None
def OnCreate(event):
point = canvas.create_oval(event.x-10, event.y-10, event.x+10, event.y+10, fill="black")
points.append(Point(point, event.x, event.y))
window = Tk()
window.wm_title("Python")
canvas = Canvas(window, width=800, height=600, background='white')
canvas.bind("<Button-1>", OnSelect)
canvas.bind("<B1-Motion>", OnMMove)
canvas.bind("<ButtonRelease-1>", OnStopDrag)
canvas.bind("<Button-3>", OnCreate)
canvas.pack(fill=BOTH, expand=YES)
window.mainloop()
As can be seen in this code, I'm using canvas.cords to move the dragged object around. Everything works fine when the mouse cursor is slowly moved while dragging, however when the mouse cursor is moved rapidly, the dragged circle seems to be partialy clipped in a rectangle while moved as seen on this picture (the whole circle is correctly drawn entirely again when dragging stops or slows down) :
I've already encountered a similar issue whend using GDI in a Win32 C application, when calling screen invalidation to repaint the window client area on the sole area covered by the initial position of the circle being currently dragged.
And indeed, when the window created in my example code is placed above a window which is constantly and entirely being redrawn, like a video game window, the cropping effect while dragging elements is not seen and the whole circle is correctly being redrawn as it is dragged.
Is there a way to solve this issue, like a canvas setting making window invalidation being called on a wider or the whole client area ? I would like to stick with Tkinter so I'm not really interested in switching to another GUI API/framework. This code has been tested on Windows 10.
