JPEG Bild in Python als Hintergrund einfügen

Fragen zu Tkinter.
Phobit
User
Beiträge: 185
Registriert: Freitag 4. Mai 2018, 18:13

wuf hat geschrieben: Samstag 28. April 2018, 11:46 Hi Freddyyy

Die fogenden drei Zeilen:
bs=Screen()
bs.register_shape("xxx.gif")
bs.bgpic("xxx.gif")
interpretiere ich wie folgt:

a)
bs=Screen()
Du erstellst eine Oberfläche(Fenster) um darauf ein Hintergrundbild zu platzieren.
b)
bs.bgpic("xxx.gif")
Ist das Hintergrundbild im .gif-Format, welches du auf dieser Oberfläche platzieren willst.
c)
bs.register_shape("xxx.gif")
Ist das Symbolbild für deine Turtle im .gif-Format, welche du auf deinem Hintergrundbild platzieren möchtest.
d)
Die .gif's willst du durch .jpeg's ersetzen und das ganze mit einem Tkinter-Skript realisieren.

Damit Tkinter mit .jpeg's umgehen kann braucht er hierfür das PIL-Modul. Das folgende Skript zeigt eine Variante wie dass ganze mit Tkinter aufgesetzt werden könnte:

Code: Alles auswählen

import tkinter as tk
from PIL import Image, ImageTk

APP_TITLE = "JPEG-Hintergrund"

app_win = tk.Tk()
app_win.title(APP_TITLE)

# Erzeugt das Hintegrund PIL-Bildobjekt 
pil_background_image = Image.open("hintergrund.jpg")
# Konvertiert das Hintegrund PIL-Bildobjekt zum Tk-Bildobjekt
app_win.tk_background_image = ImageTk.PhotoImage(pil_background_image)

# Erzeugt das Turtle PIL-Bildobjekt
pil_turtle_image = Image.open("turtle.jpg")
# Konvertiert das Turtle PIL-Bildobjekt zum Tk-Bildobjekt
app_win.tk_turtle_image = ImageTk.PhotoImage(pil_turtle_image)

# Abmessungen des Hintergrundbildes
width = app_win.tk_background_image.width()
height = app_win.tk_background_image.height()

# Erzeuge Bildfläche für das ablegen des Hintergrundbildes
canvas = tk.Canvas(app_win, width=width, height=height, highlightthickness=0)
canvas.pack()

# Legt das Hintegrundbild auf die Bildfläche
canvas.create_image(0, 0, image=app_win.tk_background_image, anchor='nw',
    tag="Hintergrund")
    
# Lege die Turle auf das Hintergrundbild
canvas.create_image(10, 10, image=app_win.tk_turtle_image, anchor='nw',
    tag="Turtle")

app_win.mainloop()
Grus wuf :wink:
Huhu,
ich habe mir mal dieses Programm abgetippt, das ist auch für mich nützlich ^^
so, aber ich habe versucht zum testen einen button drauf zu legen, mein ganzer Code (er ist einfacher gemacht als der oben) sieht dann so aus:

Code: Alles auswählen

import tkinter as tk
from PIL import Image, ImageTk


APP_TITLE = "JPEG-Hintergrund"

app_win = tk.Tk()
app_win.title(APP_TITLE)

pil_background_image = Image.open("talion.jpg")
app_win.tk_background_image = ImageTk.PhotoImage(pil_background_image)

width = app_win.tk_background_image.width()
height = app_win.tk_background_image.height()

canvas = tk.Canvas(app_win, width=width, height=height, highlightthickness=0)
canvas.pack()

canvas.create_image(0, 0, image=app_win.tk_background_image, anchor='nw', tag="Hintertgrund")


def Test():
    messagebox.showinfo(message="Test!")

button = Button(app_win, text="Testen!", command=Test, height = 10, width = 20)
button.pack()


app_win.mainloop()
Wenn ich das jetzt starte, kommt aber als Ausgabe ein Error mit "Button" is not defined...
Jemand ne Ahnung warum???
wenn ich am Anfang des Programms, so kenns ich von früher, einfach hinschreibe "from tkinter import *" kommt als Fehlercode raus AttributeError: type object 'Image' has no attribute 'open'
Mir egal, ob der Code schön ist oder nicht.
Hauptsache er funkt!
__deets__
User
Beiträge: 14493
Registriert: Mittwoch 14. Oktober 2015, 14:29

Button ist aus tkinter, und das wird als tk importiert. Du musst also tk.Button schreiben. Und Sternchenimporte sollte man genau aus dem Grund vermeiden, den du gerade erlebst: das Modul tkinter enthaelt eine Klasse Image. Das ist aber eine ganz andere als die, die du brauchst, und die aus PIL kommt. Aber durch deinen ueberbuegelnden import ist dir das nicht aufgefallen, und du importierst die falsche Klasse.

Darum NIEMALS

Code: Alles auswählen

  from irgendwas import *
machen! Sondern immer explizit was du brauchst importieren. Das kann man dann auch zur Not umbenennen. Zb

Code: Alles auswählen

 from tkinter import Image as tkImage
wenn es sein muss. Allerdings ist der

Code: Alles auswählen

 import tkinter as tk
Ansatz ehr besser.
Phobit
User
Beiträge: 185
Registriert: Freitag 4. Mai 2018, 18:13

__deets__ hat geschrieben: Freitag 18. Mai 2018, 15:31 Button ist aus tkinter, und das wird als tk importiert. Du musst also tk.Button schreiben. Und Sternchenimporte sollte man genau aus dem Grund vermeiden, den du gerade erlebst: das Modul tkinter enthaelt eine Klasse Image. Das ist aber eine ganz andere als die, die du brauchst, und die aus PIL kommt. Aber durch deinen ueberbuegelnden import ist dir das nicht aufgefallen, und du importierst die falsche Klasse.

Darum NIEMALS

Code: Alles auswählen

  from irgendwas import *
machen! Sondern immer explizit was du brauchst importieren. Das kann man dann auch zur Not umbenennen. Zb

Code: Alles auswählen

 from tkinter import Image as tkImage
wenn es sein muss. Allerdings ist der

Code: Alles auswählen

 import tkinter as tk
Ansatz ehr besser.
Ahh vielen Dank, ich mach das mit den * eh nur weil ich des in so vielen Tutorials zu tkinter lese, aber dann machs ich jetzt präziser!


Aber nichts desto trotz, auch mit tk.Button klappts nicht...zwar sind die Error jetzt weg, aber der Button wird immer noch nicht angezeigt... hier nochma der überarbeitete code:

Code: Alles auswählen

import tkinter as tk
from PIL import Image, ImageTk
from tkinter import messagebox



APP_TITLE = "JPEG-Hintergrund"

app_win = tk.Tk()
app_win.title(APP_TITLE)

pil_background_image = Image.open("talion.jpg")
app_win.tk_background_image = ImageTk.PhotoImage(pil_background_image)

width = app_win.tk_background_image.width()
height = app_win.tk_background_image.height()

canvas = tk.Canvas(app_win, width=width, height=height, highlightthickness=0)
canvas.pack()

canvas.create_image(0, 0, image=app_win.tk_background_image, anchor='nw', tag="Hintertgrund")


def Test():
    messagebox.showinfo(message="Test!")

button = tk.Button(app_win, text="Testen!", command=Test, height = 1, width = 12)
button.pack()
button.config(background='white', foreground='white')


app_win.mainloop()
Mir egal, ob der Code schön ist oder nicht.
Hauptsache er funkt!
Benutzeravatar
wuf
User
Beiträge: 1529
Registriert: Sonntag 8. Juni 2003, 09:50

Hi Phobit

Funktioniert es so besser?:

Code: Alles auswählen

import tkinter as tk
from PIL import Image, ImageTk
from tkinter import messagebox



APP_TITLE = "JPEG-Hintergrund"

app_win = tk.Tk()
app_win.title(APP_TITLE)

pil_background_image = Image.open("talion.jpg")
app_win.tk_background_image = ImageTk.PhotoImage(pil_background_image)

width = app_win.tk_background_image.width()
height = app_win.tk_background_image.height()

canvas = tk.Canvas(app_win, width=width, height=height, highlightthickness=0)
canvas.pack()

canvas.create_image(0, 0, image=app_win.tk_background_image, anchor='nw', tag="Hintertgrund")


def Test():
    messagebox.showinfo(message="Test!")

button = tk.Button(app_win, text="Testen!", command=Test, height = 1, width = 12)
button.config(background='white', foreground='white')
canvas.create_window(20, 20, window=button, anchor='nw')

app_win.mainloop()
Gruss wuf ;-)
Take it easy Mates!
Phobit
User
Beiträge: 185
Registriert: Freitag 4. Mai 2018, 18:13

wenn man de Foreground des buttons auf weiß ändert, damit man ihn auch lesen kann ja ;)
super, danke!
Mir egal, ob der Code schön ist oder nicht.
Hauptsache er funkt!
MiniDeveloper
User
Beiträge: 25
Registriert: Sonntag 3. Juni 2018, 15:09

Kleine Tipps:
Benutze PyGame oder PyQt, da geht so etwas recht fix :)
MiniDeveloper
User
Beiträge: 25
Registriert: Sonntag 3. Juni 2018, 15:09

Hi!
Ich hab mal das was Wuf gesagt hat probiert, und dieser Error kam:

Code: Alles auswählen

from PIL import Image, ImageTk
ImportError: cannot import name 'ImageTk'
Ich benutze die Python 3.5 Version, wie heißt ImageTk denn dort?

Danke für eure Hilfe :)
Benutzeravatar
ThomasL
User
Beiträge: 1366
Registriert: Montag 14. Mai 2018, 14:44
Wohnort: Kreis Unna NRW

schau mal ob dir das hier weiterhilft
http://pillow.readthedocs.io/en/5.1.x/
Ich bin Pazifist und greife niemanden an, auch nicht mit Worten.
Für alle meine Code Beispiele gilt: "There is always a better way."
https://projecteuler.net/profile/Brotherluii.png
Antworten