Programmeringsproblem i python / Tkinter [LÖST]

Elektronik- och mekanikrelaterad mjukvara/litteratur. (T.ex schema-CAD, simulering, böcker, manualer mm. OS-problem hör inte hit!)
Fox
Inlägg: 23
Blev medlem: 28 december 2004, 20:16:06
Ort: Uppsala

Programmeringsproblem i python / Tkinter [LÖST]

Inlägg av Fox »

Jag håller på att göra ett GUI med hjälp av python och Tkinter.

Koden skapar åtta knappar i en kolumn och döper dem "Configure 0" till "Configure 8"

Sen är det tänkt att knappen "Configure n" ska anropa funktionen openConfWindow(n) när man klickar på den.
Men alla knappar anropar openConfWindow(7)

Är det nån som ser varför och vet hur jag ska göra för att få det att fungera?

Här är kodstycket:

Kod: Markera allt

def init_gui():
	for i in range(8):
		f = lambda:openConfWindow(i)
		butConf = Button(root, text="Configure " + str(i), command=f)
		butConf.grid(row=i, column=5)
		butConfs.append(butConf)
Om nån vill kika på hela koden finns den här:
Hela koden
Senast redigerad av Fox 21 april 2009, 21:33:16, redigerad totalt 1 gång.
bos
Inlägg: 2308
Blev medlem: 24 februari 2007, 23:29:15
Kontakt:

Re: Programmeringsproblem i python / Tkinter

Inlägg av bos »

Att det inte funkar beror på att "i" i ditt lambda-uttryck tas från globalt scope, inte lokalt. För att iterera över en lokal variabel måste du kopiera värdet så att lambda-uttrycket får det till *sitt* lokala scope; for-loopens scope är globalt för lambda och evalueras bara en gång, därför får du samma värde (det sista loop-värdet) hela tiden.

Du löser det genom att ändra din lambda-rad till följande:

Kod: Markera allt

f = lambda i=i: openConfWindow(i)
"i=i" kan tyckas vara onödigt, men de båda är alltså två helt skilda variabler. Det vänstra tillhör lambdans lokala scope medan det högra tillhör lambdans globala scope (for-loopen).
Nerre
Inlägg: 27150
Blev medlem: 19 maj 2008, 07:51:04
Ort: Upplands väsby

Re: Programmeringsproblem i python / Tkinter

Inlägg av Nerre »

bos skrev:

Kod: Markera allt

f = lambda i=i: openConfWindow(i)
För att skriva tydligare då (utan två i):

Kod: Markera allt

f = lambda x=i: openConfWindow(x)
(Jag kan inte ett jota om python/Tk, men jag brukar vara bra på att förklara saker:-)
Fox
Inlägg: 23
Blev medlem: 28 december 2004, 20:16:06
Ort: Uppsala

Re: Programmeringsproblem i python / Tkinter

Inlägg av Fox »

Aha, nu förstår jag. Tack bos och Nerre.

Jag lägger till f() skriven i den långa syntaxen också. (I hopp om att det ska bli ännu tydligare för andra som läser tråden)

Kod: Markera allt

for i in range(8):
   def f(x=i):
      openConfWindow(x)
   butConf = Button(root, text="Configure " + str(i), command=f)
Eller allt på en rad

Kod: Markera allt

for i in range(8):
   butConf = Button(root, text="Configure " + str(i), command=lambda x=i: openConfWindow(x))
Skriv svar