Seite 1 von 1

Frage zu Parametern bei CallBack

Verfasst: Donnerstag 20. Februar 2020, 14:40
von PhilM
Hallo zusammen!
Ich habe ein kleines Programm geschrieben um das Scale-Widget unter tkinter auszuprobieren. Im Widget wird der (Benzin-)Verbrauch eingestellt, danach wird die Reichweite mit einer Tankfüllung berechnet. Klappt soweit, aber ...

def reichweite(self):
try:
stand = float(txtStand.get())
verbrauch = scwert.get()
rweite = stand*100/verbrauch
lb2["text"] = f"{rweite:8.2f}"
except:
lb2["text"] = "error"

rufe ich "reichweite()" vom Scale-Widget aus, wird verlangt die Funktion einen Parameter
rufe ich dieselbe Funktion mit einem Button auf, wird der Parameter als Fehler angezeigt.
Wie kann ich erreichen, das "Reichweite()" von beiden Widgets aus gestartet werden kann?

Vielen Dank für Eure Hilfe

Re: Frage zu Parametern bei CallBack

Verfasst: Donnerstag 20. Februar 2020, 15:32
von Sirius3
Erster Schritt wäre, das nackte `except` wegzulöschen und den tatsächlichen Fehler sich anzusehen.

Dann brauchen wir auch den kompletten Code und den wirklichen Fehler, um da was sagen zu können.
Es ist komisch, dass `reichweite` ein self-Argument hat, das aber gar nicht benutzt.

Re: Frage zu Parametern bei CallBack

Verfasst: Donnerstag 20. Februar 2020, 15:33
von __deets__
Das abfangen von allen Fehlern mit einem allumfassenden try/except ist ein Problem, denn damit verschleierst du dir ganz schnell echte Programmierfehler, statt erwartete Fehler abzufangen. Darum immer die spezifischen erwarteten Ausnahmen angeben.

Wenn dich der Parameter ansonsten nicht interessiert, kannst du mit

Code: Alles auswählen

def reichweite(self, *_args):
     ...
einfach alle zusaetzlichen Argumente abfangen. Und ignorieren. Was der einzelne Unterstrich fuer den werten Leser des Codes klarmacht per Konvention.

Re: Frage zu Parametern bei CallBack

Verfasst: Donnerstag 20. Februar 2020, 17:10
von __blackjack__
Wobei da nur ein Argument übergeben wird wenn das als Rückruf vom `scale()` verwendet wird: der aktuelle Wert.

Re: Frage zu Parametern bei CallBack

Verfasst: Donnerstag 20. Februar 2020, 18:12
von __deets__
Klar, haette man auch nen default-Argument machen koennen.

Re: Frage zu Parametern bei CallBack

Verfasst: Donnerstag 20. Februar 2020, 20:48
von PhilM
Vielen Dank!

Code: Alles auswählen

def reichweite(*_args):
hat geholfen.
Vielleicht könnt Ihr mir noch ein wenig theoretischen Background geben. Ich habe mich ja selbst auch über das "self" als Parameter gewundert, dass ja nirgendwo verwendet wird. Ich habe das ganze aus einem Python-Buch übernommen.

Dort wird bei einer Callback Funktion, die durch ein Button ausgelöst wird, auf Parameter verzichtet also

Code: Alles auswählen

def reichweite()
, dagegen beim Auslösen durch ein Scale-Widget mit self gearbeitet.

Code: Alles auswählen

def reichweite(self)
Beides für sich funktioniert. Kann mir jemand den Unterschied erklären?

Re: Frage zu Parametern bei CallBack

Verfasst: Donnerstag 20. Februar 2020, 20:56
von Sirius3
Das zeigt, dass der Autor keine Ahnung von Python- und GUI-Programmierung hat und das didaktisch auch nicht gut rüberbringen kann.

Re: Frage zu Parametern bei CallBack

Verfasst: Donnerstag 20. Februar 2020, 21:03
von PhilM
Sirius3 hat geschrieben: Donnerstag 20. Februar 2020, 20:56 Das zeigt, dass der Autor keine Ahnung von Python- und GUI-Programmierung hat und das didaktisch auch nicht gut rüberbringen kann.
Da wirst Du wohl recht haben. Erklärst Du es bitte besser?

Re: Frage zu Parametern bei CallBack

Verfasst: Donnerstag 20. Februar 2020, 21:18
von Sirius3
Wie __blackjack__ schon geschrieben hat, ist der eine Parameter, der dem Callback übergeben wird, die Position. Diese Position `self` zu nennen ist quatsch, sollte besser `position` heißen.
Ein Callback für einen Knopf hat keinen Parameter, weil außer Klick keine Information damit verbunden ist.

Auch anderen Variablennamen im Beispiel sind sehr schlecht gewählt, weil sie Abkürzungen sind, die man vermeiden sollte, weil sie einem nur das Lesen und Verstehen erschweren.

Re: Frage zu Parametern bei CallBack

Verfasst: Donnerstag 20. Februar 2020, 21:29
von PhilM
OK - Ähnlichkeitshemmung. In anderen Sprachen ist "self" vordefiniert ... Dann ist die Verwendung von self an dieser Stelle natürlich Quatsch.

Danke!

Re: Frage zu Parametern bei CallBack

Verfasst: Freitag 21. Februar 2020, 09:32
von __blackjack__
Eigentlich sollte die Signatur so aussehen:

Code: Alles auswählen

def reichweite(txtStand, scwert, lb2, *_args):
    ...
Allerdings mit vernünftigen Namen, ohne kryptische Abkürzungen, und in der Schreibweise den Konventionen bei Python entsprechend (Style Guide for Python Code).

Und `txtStand`, `scwert`, und `lb2` wären nicht auf Modulebene definiert, sondern in einer Funktion oder Methode. Und man würde `functools.partial()` verwenden um die Rückruffunktion zu erstellen, die diese Werte gebunden hat.

Oder man hätte doch ein `self` als erstes Argument wenn man das als Methode in einer Klasse definiert, wo man letztlich bei jeder nicht-trivialen GUI sowieso nicht drum herum kommt.

Re: Frage zu Parametern bei CallBack

Verfasst: Freitag 21. Februar 2020, 18:14
von PhilM
Erstmal Danke für die Hinweise.
__blackjack__ hat geschrieben: Freitag 21. Februar 2020, 09:32 Oder man hätte doch ein `self` als erstes Argument wenn man das als Methode in einer Klasse definiert, wo man letztlich bei jeder nicht-trivialen GUI sowieso nicht drum herum kommt.
Da ich Python-Anfänger bin, war mein Beispiel tatsächlich eher trivial. Aber verstehe ich Deine Aussage richtig, dass man bei nicht-trivialen GUI-Anwendungen eine Klasse für das Hauptformular erzeugt und dann eine Instanz davon?
Also in etwa

Code: Alles auswählen

class mainform:
	def __init__(self,...)
	...
	
	main =mainform( ...)
	 

Re: Frage zu Parametern bei CallBack

Verfasst: Freitag 21. Februar 2020, 19:43
von __blackjack__
@PhilM: Das ist IMHO schon an der Grenze von nicht-trivial weil an diese Funktion zwei Callbacks gebunden werden und man bei beiden eine Zwischenfunktion erstellen muss bei denen drei Widgets für den Aufruf gebunden werden.

Zum Codeschnippsel – in etwa. Aber wie gesagt: Es gibt Konventionen. Die Klasse würde eher `MainForm` heissen. Eingerückt wird mit vier Leerzeichen pro Ebene, also nicht wie im Beispiel mit Tabulatorzeichen.

Re: Frage zu Parametern bei CallBack

Verfasst: Freitag 21. Februar 2020, 21:26
von PhilM
@BlackJack

Nochmals Danke!

Und ich werde mir Mühe geben mit den Konventionen