Canvas-Objekte mit Maus bewegen

Fragen zu Tkinter.
Antworten
Benutzeravatar
wuf
User
Beiträge: 1529
Registriert: Sonntag 8. Juni 2003, 09:50

Hallo Python & Tkinter Freunde!

Hier ist noch eine Möglichkeit Tkinter-Canvas
-Objeke (mit 4 Eckpunkten x1,y1,x2,y2)
mit Hilfe der gedrückten linken Maustaste
auf einer Canvasfläche umher zu bewegen.

Vielleicht gibt es noch bessere Varianten

Code: Alles auswählen

from Tkinter import *

def MouseButton1(mouse,object):
	#~~~Setzt die Bewegungsflag
	cv.dropdragflg = TRUE
	#~~ Hebt das selektierte Objekt über die anderen
	cv.tag_raise(object,None)
	x1,y1,x2,y2 = cv.coords(object)
#	cv.update_idletasks()
	cv.xoff     = mouse.x - x1
	cv.yoff     = mouse.y - y1
	cv.x2off    = x2-x1
	cv.y2off    = y2-y1

def MouseRelease1():
	cv.dropdragflg = FALSE

def MouseMove(mouse,object):
	if cv.dropdragflg == TRUE:
		x1 = mouse.x - cv.xoff
		y1 = mouse.y - cv.yoff
		x2 = x1 + cv.x2off
		y2 = y1 + cv.y2off
		cv.coords(object,x1,y1,x2,y2)
		cv.update_idletasks()

#  ->>----CANVAS-OBJECT-MOVE WITH MOUSE----<<-
if __name__ == '__main__':

	root = Tk()
	root.title("Canvas-Move-28.01.04-22:30")
	root['bg'] = 'steelblue3'

	#~~ Erzeugt Canvasfläche für die Aufnahme von Canvas-Objekten
	cv = Canvas(root,height=430,width=450,bd=4,relief=RAISED,bg='khaki2')
	cv.pack()

	#~~ Folgende Variablen werden dem cv.objekt angehängt
	cv.dropdragflg = FALSE
	cv.xoff        = None
	cv.yoff        = None
	cv.x2off       = None
	cv.y2off       = None

	#~~~Eckkoordinaten für das Objekt gefüllter Kreis
	x0 = 50
	y0 = 50
	x1 = 200
	y1 = 200

	#~~ Zeichnet ein gefüllter Kreis
	object = cv.create_oval(x0,y0,x1,y1,fill='green',outline='darkgreen')
	# Event für linke Maustaste
	cv.tag_bind(object,"<Button-1>"       ,lambda e,Object=object:MouseButton1(e,Object))
	# Event für loslassen der linken Maustaste
	cv.tag_bind(object,"<ButtonRelease 1>",lambda e,Object=object:MouseRelease1())
	# Event für Mausbewegung
	cv.tag_bind(object,"<Motion>"         ,lambda e,Object=object:MouseMove(e,Object))

	#~~~Eckkoordinaten für das Objekt gefülltes Rechteck
	x0 = 150
	y0 = 150
	x1 = 300
	y1 = 300

	#~~ Zeichne ein gefülltes Rechteck
	object = cv.create_rectangle(x0,y0,x1,y1,fill='steelblue3',outline='darkblue')
	# Event für linke Maustaste
	cv.tag_bind(object,"<Button-1>"       ,lambda e,Object=object:MouseButton1(e,Object))
	# Event für loslassen der linken Maustaste
	cv.tag_bind(object,"<ButtonRelease 1>",lambda e,Object=object:MouseRelease1())
	# Event für Mausbewegung
	cv.tag_bind(object,"<Motion>"         ,lambda e,Object=object:MouseMove(e,Object))

	root.mainloop()
Gruss wuf
Zuletzt geändert von wuf am Donnerstag 29. Januar 2004, 20:58, insgesamt 1-mal geändert.
Take it easy Mates!
Voges
User
Beiträge: 564
Registriert: Dienstag 6. August 2002, 14:52
Wohnort: Region Hannover

Hallo!
wuf hat geschrieben:

Code: Alles auswählen

   return()
Hat es mit der Rückgabe von leeren Tupeln eine Bewandtnis?
Jan
Benutzeravatar
wuf
User
Beiträge: 1529
Registriert: Sonntag 8. Juni 2003, 09:50

Hallo Jan

Ich brauche sie nur als Platzhalter.
Gut sichtbar als Abschluss einer Funktion.
Hatte bis jetzt noch keine Probleme damit.
Ist vielleicht auch eine schlechte Ange-
wohnheit aus einer meiner früheren Sprache.

Warum die Frage? Könnten diese return()
evt. Probleme machen?

Gruss wuf
Voges
User
Beiträge: 564
Registriert: Dienstag 6. August 2002, 14:52
Wohnort: Region Hannover

Hallo!
wuf hat geschrieben:Warum die Frage? Könnten diese return()
evt. Probleme machen?
Naja, nur return fände ich aus stilistischen Gründen durchaus in Ordnung. Macht auch kein Unterschied zu ohne. Aber nur "just for fun" ein Tuple (warum gerade ein Tuple?) würd' ich nicht zurückgeben. Der Anblick verwirrt mich ein wenig, zumal das wie ein Funktionsaufruf ausieht.
Jan
Benutzeravatar
wuf
User
Beiträge: 1529
Registriert: Sonntag 8. Juni 2003, 09:50

Hallo Jan

Danke für die Antwort. Tuples gebe höchst
selten zurück. Meistens sind es einzelne
Objekte. Zum Beispiel, wenn ich eine Canvas-
fläche oder ein Canvas-Textobjekt in einer
Funktion generiere schreibe ich den Namen
der Objektvariable zwischen die Klammern
des returns. So kann ich nach Rückkehr
aus der betreffenden Funktion mit dieser Variable
an der aufrufenden Stelle weiterarbeiten.

Gruss wuf
Dookie
Python-Forum Veteran
Beiträge: 2010
Registriert: Freitag 11. Oktober 2002, 18:00
Wohnort: Salzburg
Kontaktdaten:

Hi wuf,

mit den Klammern gibst Du ein Tuple zurück, wenn auch ein leeres

Code: Alles auswählen

>>> def test1():
...     return ()
...
>>> def test2():
...     return
...
>>> print test1()
()
 
>>> print test2()
None
könnte irgendwann vielleicht doch einen seltsamen Fehler ergeben, wenn Du z.B explizit abfragst ob ein Rückgabewert None ist. Dann suchst Du dich schwarz.


Gruß

Dookie
Benutzeravatar
wuf
User
Beiträge: 1529
Registriert: Sonntag 8. Juni 2003, 09:50

Hi Dookie

Besten Dank für deinen Typ. Werde in
Zukunft darauf achten.

Gruss wuf :wink:
Antworten