Frage zu Button

Fragen zu Tkinter.
Antworten
Foxxi
User
Beiträge: 33
Registriert: Sonntag 10. Mai 2009, 16:49

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:
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))
Benutzeravatar
numerix
User
Beiträge: 2696
Registriert: Montag 11. Juni 2007, 15:09

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()
Foxxi
User
Beiträge: 33
Registriert: Sonntag 10. Mai 2009, 16:49

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?
Antworten