<<ListboxSelect>>

Fragen zu Tkinter.
Antworten
Bibo3000
User
Beiträge: 30
Registriert: Mittwoch 5. Oktober 2022, 14:01

Hallo ihr Lieben!

Ich bin gerade auf eine Frage gestoßen, die ich mir nicht selbst beantworten kann und hoffe auf eure Hilfe.
Nachfolgend der Code:

root = tk.Tk()

Listbox = tk.Listbox(root)
Listbox.insert ("end", "A", "B", "C")
Listbox.pack()

Label = tk.Label(root)
Label.pack()

def Auswahl(event):
a = Listbox.get(Listbox.curselection())
Label.config(text=str(a))

Listbox.bind("<<ListboxSelect>>", Auswahl)

root.mainloop()

Warum ist es notwendig in der Funktion "Auswahl" etwas in die Klammer zu schreiben um keinen Fehler zu generieren?
__deets__
User
Beiträge: 14545
Registriert: Mittwoch 14. Oktober 2015, 14:29

Weil ein Event binding eine Rückruffunktion erwartet, die mit einem Argument - dem Event - aufgerufen werden kann. Ob du das dann benutzt oder nicht, kann das Rahmenwerk ja nicht vorher wissen.
Benutzeravatar
__blackjack__
User
Beiträge: 13191
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

Namen werden in Python klein_mit_unterstrichen geschrieben. Ausnahmen sind Konstanten (KOMPLETT_GROSS) und Klassennamen (PascalCase).

`auswahl` wäre ein guter Name für einen Wert der eine Auswahl repräsentiert, aber nicht für eine Funktion. Funktionen (und Methoden) werden üblicherweise nach der Tätigkeit benannt die sie durchführen, damit man sie von eher passiven Werten unterscheiden kann. Bei Rückruffunktionen die eine Ereignisbehandlung machen, ist auch das Muster `on_«ereignisname»`, also beispielsweise `on_select()`.

Auf Modulebene sollte nur Code stehen, der Konstanten, Funktionen, und Klassen definiert. Das Hauptrogramm steht üblicherweise in einer Funktion die `main()` heisst.

Funktionen bekommen alles was sie ausser Konstanten benötigen, als Argument(e) übergeben.

Das heisst `auswahl()` beziehungsweise `on_select()` braucht mindestens noch das Label als Argument. Auf die Listbox könnte man über das bereits vorhandene Ereignisargument zugreifen.

Code: Alles auswählen

#!/usr/bin/env python3
import tkinter as tk
from functools import partial


def on_select(label, event):
    listbox = event.widget
    label["text"] = listbox.get(listbox.curselection())


def main():
    root = tk.Tk()

    listbox = tk.Listbox(root)
    listbox.pack()
    listbox.insert(tk.END, "A", "B", "C")

    label = tk.Label(root)
    label.pack()

    listbox.bind("<<ListboxSelect>>", partial(on_select, label))

    root.mainloop()


if __name__ == "__main__":
    main()
“There will always be things we wish to say in our programs that in all known languages can only be said poorly.” — Alan J. Perlis
Bibo3000
User
Beiträge: 30
Registriert: Mittwoch 5. Oktober 2022, 14:01

Erstmal vielen Dank für die Antworten. Ich bin leider noch relativ frisch in Python bzw. in der Programmierung generell.

@blackjack: Danke für deine ausführliche Erklärung. Das war mir so noch nicht bekannt. Diese Art der Programmierung fällt mir, zugegeben, auch noch etwas schwer vom Verständnis. Ich werde das aber künftig mehr probieren.

@deets: Danke für die Erklärung. So ganz hab ich es noch nicht verstanden. Wäre die Funktion "Auswahl" die Rückruffunktion? So ganz habe ich noch nicht verstanden warum "def Auswahl():" nicht funktioniert. Ich beziehe mich ja im Code nirgends auf "event".
Sirius3
User
Beiträge: 17792
Registriert: Sonntag 21. Oktober 2012, 17:20

Eine Rückruffunktion ist eine Funktion, die man einer anderen Funkion übergibt, damit diese die erste Funktion aufrufen kann, um bestimmte Dinge zu tun.
In Deinem Fall rufst Du `bind` mit der Rückruffunktion `Auswahl` auf, damit das TkInter-Framework diese Funktion aufrufen kann, wenn sich was an der Listbox geändert hat.
Welche Parameter die Rückruffunktion haben muß, legt `bind` fest, denn das erwartet als Argument eine Funktion mit einem Parameter (event). Wenn Du diese Erwartung nicht erfüllst, sagt `bind`: "mit dieser Art Funktion kann ich nichts anfangen" und bricht mit einem Fehler ab.
Bibo3000
User
Beiträge: 30
Registriert: Mittwoch 5. Oktober 2022, 14:01

Aaaaah, okay. Danke sehr!
Das heißt, er erwartet einfach ein Argument, selbst wenn dieses keine weitere Verwendung findet, einfach weil der Syntax es verlangt? Stimmt das in etwa?
Benutzeravatar
Dennis89
User
Beiträge: 1192
Registriert: Freitag 11. Dezember 2020, 15:13

Hallo,

genau, das meinte __deets__ auch mit folgendem Satz: (wenn ich das mal so sagen darf)
__deets__ hat geschrieben: Donnerstag 4. Mai 2023, 13:24 Ob du das dann benutzt oder nicht, kann das Rahmenwerk ja nicht vorher wissen.
Wenn du es brauchst kannst du es benutzen und wenn nicht, tust du einfach so, als ob es nicht da sein.

Grüße
Dennis
"When I got the music, I got a place to go" [Rancid, 1993]
Bibo3000
User
Beiträge: 30
Registriert: Mittwoch 5. Oktober 2022, 14:01

Vielen vielen Dank für Hilfe!
Ist immer wieder super, wenn man in so einem Forum Leute fragen kann die sich auskennen. :)
Antworten