Die Lambda-Funktion in der Widget-Bindung verwendet die Werte der letzten Iteration
Posted: 31 Dec 2024, 15:58
Ich habe eine Schleife, um Widgets dynamisch zu generieren, und die Befehle für die Schaltflächen werden mithilfe von Lambdas festgelegt, aber die Ereignisbindungen für Listboxen scheinen nicht gut zu funktionieren:
Ich bin mir nicht sicher wie, aber das lb.grid_remove() für und das Grid(...) für funktioniert ordnungsgemäß. Das für funktioniert nicht richtig.
Es funktioniert nur für das letzte Widget, weil irgendwie nur das letzte Widget nach der Schleife erhalten bleibt. obwohl ich die Variablen erfasse, wenn das Lambda definiert ist (). Es funktioniert auch nur für das letzte Widget für .
Ich habe auch functools.partial wie folgt ausprobiert:
sowohl als Schlüsselwort- als auch als Positionsargumente. Ich habe TypeError: mainfile..cbf() got multiple Values for argument 'param1' tkinter for this one.
Ich habe auch etwa 25 andere Permutationen ausprobiert und Kombinationen von Funktionsdefinitionen, deren Umhüllung und verschachtelten Rückrufen usw. Ich möchte auch keine Klassen verwenden und möchte so etwas wie das, was ich gerade mache. Bibliotheksfunktionen wie functools.partial werden ebenfalls nicht bevorzugt.
Warum funktioniert es für Befehles von Schaltflächen und einigen Bindungen, aber nicht für andere?
Hier ist ein MRE:
Warum ist der Wert des letzten Eintrags festgelegt, wenn ich die Optionen („Einige“ oder „Werte“) aus der Listbox auswähle? ist für einen anderen Eintrag gedacht? Und warum funktioniert der Fokusmechanismus?
Code: Select all
def fn1():
def cbf(e, param1, param2):
val = param2.get(param2.curselection())
param1.delete(0, tk.END)
param1.insert(0, val)
def fn2():
for x in range(n):
entry = Entry(root, textvariable=sometextvar, bg="somecolour")
lb = Listbox(root, height=someheight)
lb.insert(0, *["Some", "values"])
entry.bind("", lambda e, entry=entry: lb.grid(row=entry.grid_info()["row"] - 1, column=2, pady=0, sticky=""))
entry.bind("", lambda e: lb.grid_remove())
lb.bind("", lambda e, param1=entry, param2=lb: cbf(e, param1=param1, param2=param2))
fn1()
Es funktioniert nur für das letzte Widget, weil irgendwie nur das letzte Widget nach der Schleife erhalten bleibt. obwohl ich die Variablen erfasse, wenn das Lambda definiert ist (
Code: Select all
lambda e, param1=entry, param2=lb:
Ich habe auch functools.partial wie folgt ausprobiert:
Code: Select all
lb.bind("", partial(cbf, None, param1=entry, param2=lb))
Ich habe auch etwa 25 andere Permutationen ausprobiert und Kombinationen von Funktionsdefinitionen, deren Umhüllung und verschachtelten Rückrufen usw. Ich möchte auch keine Klassen verwenden und möchte so etwas wie das, was ich gerade mache. Bibliotheksfunktionen wie functools.partial werden ebenfalls nicht bevorzugt.
Warum funktioniert es für Befehles von Schaltflächen und einigen Bindungen, aber nicht für andere?
Hier ist ein MRE:
Code: Select all
from tkinter import Tk, Entry, Listbox, StringVar
import tkinter as tk
def fn1():
root = Tk()
def cbf(e, param1, param2):
val = param2.get(param2.curselection())
param1.delete(0, tk.END)
param1.insert(0, val)
def fn2(n):
for x in range(n):
sometextvar = StringVar()
someheight = 5
entry = Entry(root, textvariable=sometextvar, bg="red")
lb = Listbox(root, height=someheight)
lb.insert(0, *["Some", "values"])
entry.bind("",
lambda e, entry=entry: lb.grid(row=entry.grid_info()["row"] - 1, column=2, pady=0, sticky=""))
entry.bind("", lambda e: lb.grid_remove())
lb.bind("", lambda e, param1=entry, param2=lb: cbf(e, param1=param1, param2=param2))
entry.grid(row=x + 2, column=4)
fn2(5)
for r in range(root.grid_size()[1]):
root.rowconfigure(r, weight=1)
root.mainloop()
fn1()