我对Python很陌生,我现在正在玩Tkinter,看起来非常简单。我尝试使用以下代码实现简单的拖放效果(鼠标右键创建一个圆圈,鼠标左键允许拖动):
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()
从这段代码可以看出,我正在使用canvas.cords
来移动被拖动的对象。拖动时鼠标光标缓慢移动时一切正常,但是当鼠标光标快速移动时,拖动的圆圈似乎被部分剪切为矩形移动,如图所示(整体当拖动停止或减慢时,圆圈被完全正确绘制):
我在Win32 C应用程序中使用GDI时遇到过类似的问题,当调用屏幕失效来重新绘制当前拖动的圆圈初始位置覆盖的唯一区域上的窗口客户区时。
事实上,当我在我的示例代码中创建的窗口放置在一个不断重新绘制的窗口上方时,就像一个视频游戏窗口一样,拖动元素时的裁剪效果看不到,整个圆圈正在被重绘因为它被拖了。
有没有办法解决这个问题,比如在更广泛或整个客户区域调用窗口失效的画布设置?我想坚持使用Tkinter,所以我真的不想切换到另一个GUI API /框架。此代码已在Windows 10上进行了测试。
答案 0 :(得分:0)
这个答案可能会让你感到困惑(它确实是我)。但解决方案是在OnMMove中配置光标。以下是适用于Windows的摘录。
def OnMMove(event):
if selected is not None:
canvas.configure(cursor='arrow')
selected.x = event.x
selected.y = event.y
canvas.coords(selected.ref, event.x-10, event.y-10, event.x+10, event.y+10)