Seite 1 von 1

Frage zu Button

Verfasst: Sonntag 10. Mai 2009, 17:02
von Foxxi
Hallo,

ich habe mal eine Anfängerfrage zu Tkinter bzw. zu einem Button, der mit der Maus angeklickt werden kann. Ich möchte gerne, dass dann Objekte in dem Fenster verschoben werden. Im folgenden einfach mal durch einen kleinen Kreis dargestellt:

Code: Alles auswählen

def Koordinatenfenster():
	"Erzeugt ein Fenster mit einem schlichten Koordinatensystem."
	
	fenster=Tkinter.Tk()
	canvas=Tkinter.Canvas(fenster,height=920,width=920,bg="lightgrey")
	
	def start():
		canvas.move(kleinerKreis,200,200)
	
	canvas.create_line(20,460,900,460)						# X-Achse
	canvas.create_line(460,20,460,900)						# Y-Achse
	
	kleinerKreis=canvas.create_oval(30,30,35,35,fill="black")			# kleiner Kreis zum testen
	
	button=Tkinter.Button(fenster, text="los gehts", command=start())
	
	canvas.pack()
	button.pack()
	fenster.mainloop()
Das funktioniert soweit auch. Wenn ich nun aber hingehe und bei dem Funktionsaufruf einen Parameter übergebe, dann wird die Funktion start immer gleich ausgeführt, auch wenn der Button noch gar nicht angeklickt wurde. Also so:

Code: Alles auswählen

def Koordinatenfenster():
	"Erzeugt ein Fenster mit einem schlichten Koordinatensystem."
	
	fenster=Tkinter.Tk()
	canvas=Tkinter.Canvas(fenster,height=920,width=920,bg="lightgrey")
	
	def start(x):
		canvas.move(kleinerKreis,x,x)
	
	canvas.create_line(20,460,900,460)						# X-Achse
	canvas.create_line(460,20,460,900)						# Y-Achse
	
	kleinerKreis=canvas.create_oval(30,30,35,35,fill="black")			# kleiner Kreis zum testen
	
	button=Tkinter.Button(fenster, text="los gehts", command=start(200))
	
	canvas.pack()
	button.pack()
	fenster.mainloop()
Woran kann das denn wohl liegen? :roll:

Verfasst: Sonntag 10. Mai 2009, 17:54
von BlackJack
@Foxxi: Das funktioniert auch ohne Parameter so nicht, weil Du auch im ersten Beispiel die `start`-Funktion *aufrufst* statt sie zu *übergeben*.

Die beiden üblichsten Lösungen sind eine anonyme Funktion mit ``lambda`` zu definieren und als `command` zu übergeben, oder `functools.partial()` zu verwenden um eine Funktion zu erzeugen.

Code: Alles auswählen

from functools import partial
# ...
    button = Tkinter.Button(fenster, text='los gehts', command=partial(start, 200))

Verfasst: Sonntag 10. Mai 2009, 17:55
von numerix
Naja, dass die Funktion ausgeführt wird, liegt daran, dass du die Funktion AUFRUFST statt das Funktions-Objekt zu übergeben. Das kannst du z.B. mit einem lambda-Ausdruck lösen (wäre natürlich auch gut, wenn du versuchst zu verstehen, was da eigentlich passiert ...):

Code: Alles auswählen

import Tkinter

def start(x):
    canvas.move(kleinerKreis,x,x)

fenster = Tkinter.Tk()
canvas = Tkinter.Canvas(fenster,height=920,width=920,bg="lightgrey")
canvas.create_line(20,460,900,460)                      
canvas.create_line(460,20,460,900)                      
kleinerKreis = canvas.create_oval(30,30,35,35,fill="black")
button = Tkinter.Button(fenster, text="los gehts", command=lambda :start(200))
canvas.pack()
button.pack()
fenster.mainloop()

Verfasst: Montag 11. Mai 2009, 10:45
von Foxxi
Schönen Dank, das funktioniert. Tja, ich würde auch sehr gerne mehr von Tkinter usw. verstehen, aber dafür muss ich mich wohl intensiver mit der objektorientierten Seite von Python befassen. Das habe ich bisher zugegebenermassen vernachlässigt.

Leider finde ich in den Einführungen zu Python, die ich mal so durchgesehen habe, bezüglich GUI, TKinter usw. auch nur Beispiele, die entweder sehr allgemein gehalten sind oder schon wieder sehr schnell sehr speziell werden. Das ist ja leider oft ein Problem.

Hmm, wie finde ich denn da mal einen einfachen EINSTIEG in das Thema? Kann mir dazu jemand einen Tipp geben?