12 svar
81 visningar
Qetsiyah 6503 – Livehjälpare
Postad: 25 nov 2020 15:40

Loopa igenom och skapa objekt med varierande namn

Hej, se denna video. Vid 48:10 håller han på att skapa en enkel miniräknare och ska göra knappar för 1,2,3,4,5,6,7,8,9,0, men det ser väldigt klumpigt ut, hur kan man göra det där med en loop istället? Typ "for i in range(9)" skapa knappar med namnen "button_i".

Skaft 2373 – F.d. Moderator
Postad: 25 nov 2020 15:48

När man börjar göra en bunt variabler med liknande namn, är det vanligen en dictionary man egentligen borde använda. Så istället för många knapp-variabler, kan du ha en dictionary som håller alla knappobjekten, under rimliga namn:

buttons = {
  '1': Button(root, text='1', padx=40, pady=20, command=...),
  '2': Button(root, text='2', padx=40, pady=20, command=...),
}

Men att skriva på det här sättet blir också väldigt upprepande. Istället kan man göra en dict comprehension:

names = ['1', '2', '3', ...]
buttons = {
  name: Button(root, text=name, padx=40, pady=20, command=...)
  for name in names
}
Qetsiyah 6503 – Livehjälpare
Postad: 25 nov 2020 15:50 Redigerad: 25 nov 2020 15:50

Just ja, men behöver inte det sista "for name in names" vara på samma rad som föregående rad? Eller kan det vara en rad ovanför`?

Skaft 2373 – F.d. Moderator
Postad: 25 nov 2020 15:53

Nej, det behöver inte vara på samma rad, det behöver bara komma efter key:value-paret. Vanligen står det på samma rad, men nu tyckte jag value-kommandot blev så långt, så jag satte själva loopraden separat.

Qetsiyah 6503 – Livehjälpare
Postad: 25 nov 2020 15:54

Okej, tack så mycket!

Qetsiyah 6503 – Livehjälpare
Postad: 25 nov 2020 16:19

Nu gjorde jag såhär, men mina frames packas inte!

Skaft 2373 – F.d. Moderator
Postad: 25 nov 2020 16:26

pack är la en funktion, då måste du anropa den med parenteser: pack()

Qetsiyah 6503 – Livehjälpare
Postad: 25 nov 2020 16:27 Redigerad: 25 nov 2020 16:29

Jag fixade det men det fungerar fortfarande inte. Det fungerar inte för att det står ""Resultat" not defined" när jag försöker lägga in knappar i resultat-framen.

Skaft 2373 – F.d. Moderator
Postad: 25 nov 2020 16:32

Det låter som kod du inte visat än. Hur ser den biten ut?

Qetsiyah 6503 – Livehjälpare
Postad: 25 nov 2020 16:34
butt1 =  Button(Resultat, text="Click me", command=textadder, bg="red").pack()

Så ser det ut

Skaft 2373 – F.d. Moderator
Postad: 25 nov 2020 16:39

Resultat är inte en variabel. Om du vill använda den LabelFrame du skapat med namnet "Resultat" kommer du åt den med frames_dic['Resultat'].

Qetsiyah 6503 – Livehjälpare
Postad: 25 nov 2020 16:42 Redigerad: 25 nov 2020 16:47

Ah det funkar nu.

Skulle jag kunna undvika det jag skriver på rad 15, 16 och packa direkt i dictionaryn?

edit: nej det funkar inte, men varför?

Skaft 2373 – F.d. Moderator
Postad: 25 nov 2020 16:55

En sak du kan göra är att loopa genom dina labelframes direkt, utan att gå via deras namn:

for labelframe in frames_dic.values():
  labelframe.pack()

Men om du menar att göra .pack() "samtidigt" som din labelframe skapas, då får du nog skippa en comprehension och skapa din dict på mer traditionellt vis:

names = ['Resultat', 'etc']
frames_dic = {}
for name in names:
  labelframe = LabelFrame(root, text=name, ...)
  frames_dic[name] = labelframe
  labelframe.pack()
Svara Avbryt
Close