Seite 1 von 1

Buttons in Schleife erstellen

Verfasst: Freitag 11. Juli 2014, 13:47
von AndiArbeit
Hallo liebes Pythonforum,

Ich möchte in Python 2.7 in einer Schleife Buttons generieren. Mit den Buttons soll ein Link in einem Browser geöffnet werden. Somit ein Button für jeden Eintrag der Liste. Die Länge de rliste ist allerdings Variabel. Ein Auszug meines Quelltexts sieht folgendermaßen aus.

Code: Alles auswählen

from Tkinter import *
links = ["www.google.de","www.python-forum.de/"] # Meine liste wird automatisch generiert, hier nur Beispielhaft
for link in links :
    Button(command = lambda: webbrowser.open(link)).grid(row = reihe, column = spalte )
Das Problem ist, das jetzt leider bei jedem Button nur der letzte Eintrag der Liste angesprochen wird. Ist mir auch klar, da die lambda Funktion ja jedes mal überschrieben wird.

Hat jemand eine Idee wie ich das Problem lösen kann ?
Danke schonmal im Voraus

Gruß AndiArbeit

Re: Buttons in Schleife erstellen

Verfasst: Freitag 11. Juli 2014, 14:00
von MagBen
Ungetestet:

Code: Alles auswählen

def createButton(link):
    return Button(command = lambda: webbrowser.open(link))

for link in links :
    createButton(link).grid(row = reihe, column = spalte )

Re: Buttons in Schleife erstellen

Verfasst: Freitag 11. Juli 2014, 15:01
von BlackJack
@AndiArbeit: Das löst man mit `functools.partial()`:

Code: Alles auswählen

for link in links :
    Button(command=partial(webbrowser.open, link).grid(row=reihe,column=spalte)

Re: Buttons in Schleife erstellen

Verfasst: Freitag 11. Juli 2014, 15:35
von cofi
Oder direkt mit `lambda`:

Code: Alles auswählen

In [8]: from __future__ import print_function

In [9]: funs = [lambda: print(x) for x in "a", "b", "c"]

In [10]: for f in funs: f()
c
c
c

In [11]: funs = [lambda x=x: print(x) for x in "a", "b", "c"]

In [12]: for f in funs: f()
a
b
c
Das Problem ist, dass `x` (oder bei dir `link`) nicht bei der Erstellung des `lambda` gebunden wird. Indem man das ueber einen default-Parameter loest kann man das simulieren.

Re: Buttons in Schleife erstellen

Verfasst: Freitag 11. Juli 2014, 20:16
von Ene Uran
Ich glaube dass partial() einfacher ist zum verstehen ...

Code: Alles auswählen

import webbrowser
# use namespace
import Tkinter as tk
from functools import partial

root = tk.Tk()

# Meine liste wird automatisch generiert, hier nur Beispielhaft
links = ["www.google.de","www.python-forum.de/"]
reihe = 0
spalte = 0
for link in links :
    s = link.split('.')[1]
    cmd = partial(webbrowser.open, link)
    tk.Button(root, text=s, command=cmd).grid(row=reihe, column=spalte)
    reihe += 1

root.mainloop()

Re: Buttons in Schleife erstellen

Verfasst: Freitag 11. Juli 2014, 21:40
von pillmuncher
@Ene Uran: Ich glaube dass enumerate() einfacher ist zum verstehen ...

Code: Alles auswählen

spalte = 0
for reihe, link in enumerate(links):
    s = link.split('.')[1]
    cmd = partial(webbrowser.open, link)
    tk.Button(root, text=s, command=cmd).grid(row=reihe, column=spalte)

Re: Buttons in Schleife erstellen

Verfasst: Samstag 12. Juli 2014, 13:08
von AndiArbeit
Funktioniert :D

Vielen Dank für die schnelle und kompetente Hilfe

Re: Buttons in Schleife erstellen

Verfasst: Sonntag 13. Juli 2014, 23:02
von Ene Uran
@pillmuncher, schon richtig, aber reihe muss nicht unbedingt mit null anfangen, kommt auf den Rest der GUI an.

Re: Buttons in Schleife erstellen

Verfasst: Sonntag 13. Juli 2014, 23:15
von pillmuncher
Ene Uran hat geschrieben:@pillmuncher, schon richtig, aber reihe muss nicht unbedingt mit null anfangen, kommt auf den Rest der GUI an.
Ok:

Code: Alles auswählen

>>> [x for x in enumerate('hallo', start=123)]
[(123, 'h'), (124, 'a'), (125, 'l'), (126, 'l'), (127, 'o')]