2017-05-18 6 views
2

Ich bin ziemlich neu in Python und ich spiele gerade ein bisschen mit Tkinter, die erstaunlich einfach aussieht. Ich habe versucht, einen einfachen Drag zu implementieren und Wirkung fällt mit dem folgenden Code (rechte Maustaste erzeugt einen Kreis, linke Maustaste ermöglicht ziehen):Tkinter Canvas-Invalidisierungsproblem (Objekt abgeschnitten, während verschoben)

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() 

Wie in diesem Code zu sehen, ich bin mit canvas.cords, um das gezogene Objekt zu verschieben. Alles funktioniert gut, wenn der Mauszeiger während des Ziehens langsam bewegt wird. Wenn der Mauszeiger jedoch schnell bewegt wird, scheint der gezogene Kreis teilweise in einem Rechteck geclippt zu sein, während er auf diesem Bild verschoben ist (der ganze Kreis ist korrekt gezeichnet)

Drag and drop cropping issue illustrated

ich erlebt habe bereits ein ähnliches Problem whend in einer Win32-C-Anwendung GDI verwenden, wenn der Bildschirm Ungültigkeits Aufrufen der Fenster Client-Bereich auf dem Sohlenbereich neu zu zeichnen bedeckt: wieder, wenn stoppt oder verlangsamt) ziehen durch die anfängliche Position des Kreises, der gerade gezogen wird. Wenn das in meinem Beispielcode erzeugte Fenster über einem Fenster platziert wird, das ständig und vollständig neu gezeichnet wird, wie ein Videospielfenster, wird der Beschneidungseffekt beim Ziehen von Elementen nicht gesehen und der ganze Kreis ist korrekt neu gezeichnet, wie es gezogen wird.

Gibt es eine Möglichkeit, dieses Problem zu lösen, wie eine Canvas-Einstellung, die dazu führt, dass das Fenster für einen größeren oder den gesamten Client-Bereich ungültig wird? Ich würde gerne bei Tkinter bleiben, so dass ich nicht wirklich daran interessiert bin, zu einem anderen GUI-API/Framework zu wechseln. Dieser Code wurde unter Windows 10 getestet.

+1

Ich kann dies auf Linux nicht duplizieren und haben keinen Zugriff auf eine Windows-Box. Es gibt nicht viel, was Sie tun können, um zu ändern, wie tkinter Fenster aktualisiert. Das ist auf der TK-Ebene nicht sichtbar. –

Antwort

0

Diese Antwort kann Sie verwirren (es tut mir). Eine Lösung besteht darin, den Cursor in OnMMove zu konfigurieren. Hier ist der Ausschnitt, der für mich bei Windows funktioniert hat.

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) 
Verwandte Themen