Seite 1 von 1
Bilder auf Button
Verfasst: Mittwoch 6. August 2014, 13:26
von AndiArbeit
Hallo liebes Python Forum,
ich habe bei einem Projekt ein kleines Problem. Ich habe eine Liste von Bildern (die Länge der liste ist unbekannt) und möchte diese Bilder auf Buttons darstellen.
Ein Teil meines Scripts sieht folgendermaßen aus.
Code: Alles auswählen
from PIL import Image, ImageTk
from Tkinter import *
def buttonmaker():
reihe = 0
spalte = 0
bilder = [bild1, bild2, bild3, ... ]
for bild in bilder :
image = PhotoImage(file=bild)
Button(root ,image = image).grid(row = reihe, column = spalte)
spalte += 1
if spalte > 3 :
spalte = 0
reihe += 1
root = Tk()
buttonmaker()
mainloop()
Das Problem ist, dass die Bilder nicht dargestellt werden. Das liegt wohl daran, dass Tkinter wahrscheinlich die Informationen der überschriebenen Images benötigt. Hat jemand eine Idee wie ich das lösen könnte ?
Vielen Dank im Vorraus
Gruß AndiArbeit
Re: Bilder auf Button
Verfasst: Mittwoch 6. August 2014, 13:30
von BlackJack
@AndiArbeit: Solange die Bilder angezeigt werden musst Du eine Referenz auf die Bildobjekte behalten. Also sie zum Beispiel in einer Liste speichern.
Re: Bilder auf Button
Verfasst: Mittwoch 6. August 2014, 13:37
von EyDu
Die for-Schleife geht noch ein wenig einfacher:
Code: Alles auswählen
for index, bild in enumerate(bilder):
zeile, spalte = divmod(index, 3)
...
Re: Bilder auf Button
Verfasst: Mittwoch 6. August 2014, 13:55
von BlackJack
Ungetestet:
Code: Alles auswählen
import Tkinter as tk
from PIL import ImageTk
def create_image_buttons(master, image_paths, buttons_per_row=3):
images = [ImageTk.PhotoImage(file=path) for path in image_paths]
frame = tk.Frame(master)
frame.images = images
for i, image in enumerate(images):
row, column = divmod(i, buttons_per_row)
tk.Button(frame, image=image).grid(row=row, column=column)
return frame
def main():
image_paths = ['bild1', 'bild2', 'bild3']
root = tk.Tk()
frame = create_image_buttons(root, image_paths)
frame.pack()
root.mainloop()
if __name__ == '__main__':
main()
Re: Bilder auf Button
Verfasst: Mittwoch 6. August 2014, 14:58
von Ene Uran
@EyDu, etwas besser ...
zeile, spalte = divmod(index, max_spalten)
Ach du lieber, schon gemacht, da mach ich den Putin verantwortlich!
Re: Bilder auf Button
Verfasst: Donnerstag 7. August 2014, 07:36
von AndiArbeit
Vielen Dank für die schnelle Hilfe.
Mein Script läuft leider immer noch nicht wie es soll. Bei den Bildern handelt es sich um jpg Dateien.
Im Grunde geht es im Script darum das ich mir aus der Schlagzeilenseite von Spiegel.de die Links und Titelbilder ziehe und dann die Bilder und Links auf die Buttons setzen will. Leider werden die jpgs nicht dargestellt.
Ich geh davon aus das ich das ich PIL nicht richtig verwende.
Für Korrekturen bin ich sehr Dankbar
Gruß AndiArbeit
Code: Alles auswählen
from PIL import Image, ImageTk
from Tkinter import *
def buttonmaker():
reihe = 0
spalte = 0
counter = 0
imageliste = []
bilder = ["bild1.jpg", "bild2.jpg", "bild3.jpg", ... ]
for bild in bilder :
image = Image.open(bild)
photo = ImageTk.PhotoImage(image)
imageliste += [photo]
Button(root ,image = imageliste[counter]).grid(row = reihe, column = spalte)
counter += 1
spalte += 1
if spalte > 3 :
spalte = 0
reihe += 1
root = Tk()
buttonmaker()
mainloop()
Re: Bilder auf Button
Verfasst: Donnerstag 7. August 2014, 08:41
von BlackJack
@AndiArbeit: Du musst dafür sorgen das solange die Bilder angezeigt werden, auch die Bildobjekte in Python existieren. Du sammelst die zwar (sehr umständlich) in `imageliste`, aber wenn die Funktion `buttonmaker()` zu ende ausgeführt wurde, verschwindet diese Liste und damit auch die Bildobjekte.
Re: Bilder auf Button
Verfasst: Donnerstag 7. August 2014, 08:54
von AndiArbeit
@ BlackJack Vielen Dank jetzt läuft es. Habe meine Liste als Globale Variable angegeben. Ich weiß das ist eine hässliche Methode aber es läuft

. Nur für Lernzwecke wie hättest du Bildobjekte gesammelt ?
Re: Bilder auf Button
Verfasst: Donnerstag 7. August 2014, 08:56
von BlackJack
@AndiArbeit: Ich hatte da ja schon einen Beitrag mit Quelltext zu geschrieben.
Edit:
Code: Alles auswählen
import Tkinter as tk
from functools import partial
from io import BytesIO
from itertools import imap
import requests
from bs4 import BeautifulSoup
from PIL import Image, ImageTk
BASE_URL = 'http://www.spiegel.de'
TOP_HEADLINES_URL = BASE_URL + '/schlagzeilen/tops/index.html'
class ArticleButton(tk.Button):
def __init__(self, master, url, headline, image, headline_label):
image = ImageTk.PhotoImage(image)
tk.Button.__init__(self, master, image=image, command=self._clicked)
self.image = image
self.url = url
self.headline = headline
self.headline_label = headline_label
self.bind(
'<Enter>', lambda _: headline_label.configure(text=self.headline)
)
self.bind('<Leave>', lambda _: headline_label.configure(text=''))
def _clicked(self):
print self.url
class ArticlesFrame(tk.Frame):
def __init__(self, master, articles, articles_per_row=6):
tk.Frame.__init__(self, master)
headline_label = tk.Label(self)
headline_label.pack()
button_frame = tk.Frame(self)
for i, (url, headline, image) in enumerate(articles):
button = ArticleButton(
button_frame, url, headline, image, headline_label
)
row, column = divmod(i, articles_per_row)
button.grid(row=row, column=column)
button_frame.pack()
def scrape_headline_link(base_url, link_node):
return (
base_url + link_node['href'],
link_node['title'],
Image.open(BytesIO(requests.get(link_node.img['src']).content))
)
def scrape_headlines(base_url, headlines_url):
return imap(
partial(scrape_headline_link, base_url),
BeautifulSoup(requests.get(headlines_url).text).select(
'div.schlagzeilen-content div.article-image-box a'
)
)
def main():
root = tk.Tk()
articles_frame = ArticlesFrame(
root, scrape_headlines(BASE_URL, TOP_HEADLINES_URL)
)
articles_frame.pack()
root.mainloop()
if __name__ == '__main__':
main()
Re: Bilder auf Button
Verfasst: Freitag 8. August 2014, 09:40
von jens
btw. damit das Bild nicht vom GC gelöscht wird, könnte man es auch an einem Button object packen, siehe Beispiel hier:
http://tkinter.unpythonic.net/wiki/Phot ... PhotoImage