Angenommen, ich habe Folgendes Button
mit Tkinter in Python erstellt:
import Tkinter as Tk
win = Tk.Toplevel()
frame = Tk.Frame(master=win).grid(row=1, column=1)
button = Tk.Button(master=frame, text='press', command=action)
Die Methode action
wird aufgerufen, wenn ich die Taste drücke. Was ist, wenn ich der Methode einige Argumente übergeben möchte action
?
Ich habe es mit folgendem Code versucht:
button = Tk.Button(master=frame, text='press', command=action(someNumber))
Dies ruft die Methode sofort auf und das Drücken der Taste bewirkt nichts.
Antworten:
Ich persönlich bevorzuge die Verwendung
lambdas
in einem solchen Szenario, da es imo klarer und einfacher ist und Sie auch nicht zwingt, viele Wrapper-Methoden zu schreiben, wenn Sie nicht die Kontrolle über die aufgerufene Methode haben, aber das ist sicherlich Geschmackssache.So würden Sie es mit einem Lambda machen (beachten Sie, dass es auch eine Implementierung von Currying im Funktionsmodul gibt, damit Sie das auch verwenden können):
quelle
partial
funktioniert in diesem Fall."This just invokes the method immediately, and pressing the button does nothing"
passiert?callback=lambda x=x: f(x)
wie infs = [lambda x=x: x*2 for x in range(5)] ; print [f() for f in fs]
Dies kann auch mithilfe
partial
der folgenden Funktionsfunktionen der Standardbibliothek erfolgen :quelle
button = Tk.Button(master=frame, text='press', command=partial(action, arg))
action_with_args = partial(action, arg1, arg2... argN)
Beispiel GUI:
Angenommen, ich habe die GUI:
Was passiert, wenn eine Taste gedrückt wird?
Beachten Sie, dass beim
btn
Drücken eine eigene Funktion aufgerufen wird, die derbutton_press_handle
im folgenden Beispiel sehr ähnlich ist :mit:
Sie können sich einfach vorstellen, dass diese
command
Option als Verweis auf die Methode festgelegt werden sollte, die aufgerufen werden soll, ähnlich wiecallback
inbutton_press_handle
.Aufrufen einer Methode ( Rückruf ) Wenn die Taste gedrückt wird
Ohne Argumente
Wenn ich also
print
etwas wollte, wenn die Taste gedrückt wird, müsste ich Folgendes einstellen:Achten Sie auf das Fehlen von
()
mit demprint
Verfahren , das im Sinne weggelassen wird , dass: „Das ist der Name der Methode, die ich Sie wollen , wenn sie gedrückt nennen , aber . Sie es nicht nur diesem Augenblick nennen“ Ich habe jedoch keine Argumente für das übergeben,print
sodass gedruckt wurde, was auch immer gedruckt wird, wenn es ohne Argumente aufgerufen wird.Mit Argument (en)
Wenn ich nun auch Argumente an die Methode übergeben möchte, die beim Drücken der Schaltfläche aufgerufen werden soll, kann ich die anonymen Funktionen verwenden, die mit der Lambda- Anweisung erstellt werden können, in diesem Fall für die
print
integrierte Methode wie die folgende ::Aufrufen mehrerer Methoden, wenn die Taste gedrückt wird
Ohne Argumente
Sie können dies auch mit der
lambda
Anweisung erreichen, aber es wird als schlechte Praxis angesehen, und daher werde ich es hier nicht aufnehmen. Es empfiehlt sich, eine separate Methode zu definierenmultiple_methods
, die die gewünschten Methoden aufruft und diese dann als Rückruf für den Tastendruck festlegt:Mit Argument (en)
Um Argumente an Methoden zu übergeben, die andere Methoden aufrufen, verwenden Sie erneut die
lambda
Anweisung, aber zuerst:und dann setzen:
Rückgabe von Objekten aus dem Rückruf
Beachten Sie auch, dass
callback
dies nicht wirklich möglich ist,return
da es nurbutton_press_handle
mitcallback()
im Gegensatz zu aufgerufen wirdreturn callback()
. Es tutreturn
aber nicht überall außerhalb dieser Funktion. Daher sollten Sie lieber Objekte ändern , auf die im aktuellen Bereich zugegriffen werden kann.Vollständiges Beispiel mit globalen Objektmodifikationen.
Das folgende Beispiel ruft eine Methode auf, die
btn
den Text jedes Mal ändert , wenn die Taste gedrückt wird:Spiegel
quelle
Die Fähigkeit von Python, Standardwerte für Funktionsargumente bereitzustellen, gibt uns einen Ausweg.
Siehe: http://infohost.nmt.edu/tcc/help/pubs/tkinter/web/extra-args.html
Für weitere Schaltflächen können Sie eine Funktion erstellen, die eine Funktion zurückgibt:
quelle
myX
undmyY
perfekt funktioniert. Vielen Dank.Aufbauend auf Matt Thompsons Antwort: Eine Klasse kann aufrufbar gemacht werden, sodass sie anstelle einer Funktion verwendet werden kann:
quelle
Der Grund, warum die Methode sofort aufgerufen wird und das Drücken der Taste nichts bewirkt, ist der folgende
action(somenumber)
ausgewertet wird und ihr Rückgabewert als Befehl für die Schaltfläche zugewiesen wird. Wenn Sie alsoaction
etwas drucken, das Ihnen mitteilt, dass es ausgeführt wurde und zurückkehrtNone
, führen Sie es einfach ausaction
, um den Rückgabewert auszuwerten, und geben Sie esNone
als Befehl für die Schaltfläche an.Um Schaltflächen zum Aufrufen von Funktionen mit unterschiedlichen Argumenten zu haben, können Sie globale Variablen verwenden, obwohl ich es nicht empfehlen kann:
Was ich tun würde, ist ein
class
Objekt zu erstellen, dessen Objekte alle erforderlichen Variablen und Methoden enthalten, um diese nach Bedarf zu ändern:quelle
Ich glaube, das sollte behoben werden
quelle
Am besten verwenden Sie Lambda wie folgt:
quelle
Ich bin sehr spät dran, aber hier ist eine sehr einfache Möglichkeit, dies zu erreichen.
Sie verpacken einfach die Funktion, die Sie verwenden möchten, in eine andere Funktion und rufen die zweite Funktion beim Drücken der Taste auf.
quelle
var1
undvar2
Hauptmodul in, können Sie überspringenfunction1
überhaupt und setzenprint
in der Aussagefunction2
. Beziehen Sie sich auf andere Situationen, die ich nicht verstehe?Lambdas sind alle gut und schön, aber Sie können dies auch versuchen (was übrigens in einer for-Schleife funktioniert):
Dies funktioniert, da beim Festlegen der Bindung ein Tastendruck das Ereignis als Argument übergibt. Sie können dann Attribute außerhalb des Ereignisses aufrufen
event.char
, um "1" oder "UP" zu erhalten. Wenn Sie ein Argument oder mehrere andere Argumente als die Ereignisattribute benötigen. Erstellen Sie einfach ein Wörterbuch, um sie zu speichern.quelle
Ich bin auch schon einmal auf dieses Problem gestoßen. Sie können nur Lambda verwenden:
quelle
Verwenden Sie ein Lambda, um die Eingabedaten an die Befehlsfunktion zu übergeben, wenn Sie weitere Aktionen ausführen müssen (ich habe versucht, sie generisch zu machen, also passen Sie sie einfach an):
Dadurch werden die Informationen im Ereignis an die Tastenfunktion übergeben. Es gibt vielleicht mehr pythoneske Schreibweisen, aber es funktioniert für mich.
quelle
JasonPy - ein paar Dinge ...
Wenn Sie einen Knopf in eine Schleife stecken, wird er immer und immer wieder erstellt ... was wahrscheinlich nicht das ist, was Sie wollen. (vielleicht ist es)...
Der Grund, warum immer der letzte Index abgerufen wird, sind Lambda-Ereignisse, die ausgeführt werden, wenn Sie darauf klicken - nicht, wenn das Programm gestartet wird. Ich bin mir nicht 100% sicher, was Sie tun, aber versuchen Sie vielleicht, den Wert zu speichern, wenn er erstellt wurde, und rufen Sie ihn später mit der Lambda-Taste auf.
zB: (benutze diesen Code nicht, nur ein Beispiel)
dann kann man sagen ....
hoffe das hilft!
quelle
Eine einfache Möglichkeit wäre die Konfiguration
button
mitlambda
der folgenden Syntax:quelle
Für die Nachwelt: Sie können auch Klassen verwenden, um etwas Ähnliches zu erreichen. Zum Beispiel:
Die Schaltfläche kann dann einfach erstellt werden durch:
Mit diesem Ansatz können Sie auch die Funktionsargumente ändern, indem Sie sie einstellen
instance1.x = 3
.quelle
Sie müssen verwenden
lambda:
quelle
Verwenden Sie Lambda
Ausgabe:
quelle