tk:button - command=lambda: ....

Fragen zu Tkinter.
Antworten
turbosoeckchen
User
Beiträge: 13
Registriert: Sonntag 8. September 2019, 15:35

Hallo zusammen,

da ich gerade in einem Fenster 20 Buttons erstellen möchte, habe ich keine Luste das ganze manuell zu machen :lol:
Die Buttons sollen jedoch immer die gleiche Funktion ausführen, mit der für den Button besonderen Variablen - in diesem Falle eine aufsteigende Zahl

Hier mal der Code soweit:

Code: Alles auswählen

    buttons = []
    for each in vg.knotenmatrix:
        buttons.append(tk.Button(frame_r, text=each.nummer, command=lambda: knotencall(each.nummer),  bg="gray", height=1, width=2))
        print(each.nummer)
        buttons[each.nummer].place(relx=nm.buttonposition_hard[each.nummer][0], rely=nm.buttonposition_hard[each.nummer][1])
command=lambda: knotencall(each.nummer) ist der Knackpunkt.

Das dunktioniert zwar, aber nicht wie gewollt :)! - Egal welchen Button ich drücke, es wird immer der Wert letzte "each.nummer" Nummer wert genommen. Wie kann ich das ändern, sodass dem Button der richtige Wert mitgegeben wird?

Vielen Dank für Eure Hilfe :)


PS: Die Funktion, die der Button anspricht wäre erst einmal diese:

Code: Alles auswählen

def knotencall(i):
    kp.knotenmenu(i)
Wieso auch immer das noch verdoppelt ist... Aber das ist für später
Benutzeravatar
__blackjack__
User
Beiträge: 13080
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@turbosoeckchen: Du suchst `functools.partial()`.
„All religions are the same: religion is basically guilt, with different holidays.” — Cathy Ladman
Sirius3
User
Beiträge: 17741
Registriert: Sonntag 21. Oktober 2012, 17:20

Der Code sieht seltsam aus. Woher kommen vg, nm oder kp? Das sieht stark nach globalen Variablen aus
Wenn das mit der buttons-Liste funktionieren soll, muss each.nummer von 0 aufsteigend sein, und damit überflüssig, weil die Information schon in der Position innerhalb der Liste gegeben ist.
turbosoeckchen
User
Beiträge: 13
Registriert: Sonntag 8. September 2019, 15:35

Sirius3 hat geschrieben: Sonntag 22. September 2019, 12:58 Der Code sieht seltsam aus. Woher kommen vg, nm oder kp? Das sieht stark nach globalen Variablen aus
Wenn das mit der buttons-Liste funktionieren soll, muss each.nummer von 0 aufsteigend sein, und damit überflüssig, weil die Information schon in der Position innerhalb der Liste gegeben ist.
Das sind auch globale Variablen, die an einem anderen Ort gespeichert stehen.
"each.nummer" ist tatsächlich ein Zähler, der von 0 startet und bis 19 läuft.

D.h. ich muss hier mit partial arbeiten? Ich kann lambda also nicht verwenden?
Benutzeravatar
__blackjack__
User
Beiträge: 13080
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@turbosoeckchen: Man kann auch einen ``lambda``-Ausdruck verwenden, aber `functools.partial()` gibt es ja extra dafür.

Globale Variablen sollte man nicht verwenden. Alles was eine Funktion/Methode ausser Konstanten benötigt sollte als Argument(e) übergeben werden. Die Namen gehen für globale Variablen auch überhaupt nicht. Je grösser der Sichtbarkeitsbereich von Variablen ist, desto wichtiger ist es das die aussagekräftig benannt sind. Ein- oder zweibuchstabenkürzel gehen als Argumente bei ``lambda``-Ausdrücken oder für Namen die lokal zu „comprehensions“ sind, aber nicht darüber hinaus.

Etwas schräg ist auch der Deutsch/Englisch-Mix bei den Namen.

Was bei dem Index auch ein bisschen komisch riecht ist das es anscheinend mehrere ”parallele” Datenstrukturen gibt, wo immer an diesem Index Informationen verteilt sind, die ja offensichtlich zusammengehören. So etwas ist unübersichtlich bis fehleranfällig.
„All religions are the same: religion is basically guilt, with different holidays.” — Cathy Ladman
turbosoeckchen
User
Beiträge: 13
Registriert: Sonntag 8. September 2019, 15:35

__blackjack__ hat geschrieben: Sonntag 22. September 2019, 15:44 @turbosoeckchen: Man kann auch einen ``lambda``-Ausdruck verwenden, aber `functools.partial()` gibt es ja extra dafür.

Globale Variablen sollte man nicht verwenden. Alles was eine Funktion/Methode ausser Konstanten benötigt sollte als Argument(e) übergeben werden. Die Namen gehen für globale Variablen auch überhaupt nicht. Je grösser der Sichtbarkeitsbereich von Variablen ist, desto wichtiger ist es das die aussagekräftig benannt sind. Ein- oder zweibuchstabenkürzel gehen als Argumente bei ``lambda``-Ausdrücken oder für Namen die lokal zu „comprehensions“ sind, aber nicht darüber hinaus.

Etwas schräg ist auch der Deutsch/Englisch-Mix bei den Namen.

Was bei dem Index auch ein bisschen komisch riecht ist das es anscheinend mehrere ”parallele” Datenstrukturen gibt, wo immer an diesem Index Informationen verteilt sind, die ja offensichtlich zusammengehören. So etwas ist unübersichtlich bis fehleranfällig.
Ich bin ganz am Anfang meiner Karriere :lol: ... Ja schön ist was anderes, aber es soll erst einmal funktionieren. Dazu räume ich jetzt schon auf und passe viele Funktionen stark an.
Aber hast du einen Tip WIE ich es hinbekomme, dass dem Knoten genau DER Wert der Laufvariablen mitgegeben wird? und das sich nicht mehr weiter ändert?

Vielen Dank an alle Helfenden.
Sirius3
User
Beiträge: 17741
Registriert: Sonntag 21. Oktober 2012, 17:20

Normalerweise ist es überhaupt nicht nötig, einen Index zu verwenden. Alles was zusammem gehört wird in einem Objekt gebündelt und als Objekt an Funktionen weitergereicht, die es brauchen.

PS: du brauchst nicht immer den vollständigen Beitrag zitieren, denn der steht ja direkt darüber.
Benutzeravatar
__blackjack__
User
Beiträge: 13080
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@turbosoeckchen: Anfang der Karriere ist nur bedingt ein Argument. Man sollte halt gar nicht erst mit globalen Variablen anfangen. 🙂
„All religions are the same: religion is basically guilt, with different holidays.” — Cathy Ladman
Antworten