Seite 1 von 1

Problem mit tkinter.PhotoImage

Verfasst: Donnerstag 11. Mai 2023, 18:00
von DerBotaniker
Liebe alle,

ich bin in letzter Zeit damit beschäftigt, mich in tkinter einzuarbeiten und stoße dabei aber auf das Problem, dass ich bei hoffentlich richtiger Übernahme des Codes aus dem Python 3 Handbuch von Ernesti und Kaiser (6. Aufl., S. 862) trotzdem das Programm nicht starten kann. Nach einer Weile habe ich herausgefunden, dass es ausschließlich an den Zeilen 8 und 9 liegt. Es spielt keine Rolle, wie komplex ich den Datei-Pfad gestalte. Es scheint so, als könnte Python mit den Befehlen nicht umgehen...

import tkinter
class MyApp(tkinter.Frame):
def __init__(self, master):
super().__init__(master)
self.pack()
self.cv=tkinter.Canvas(self, width=800, height=600)
self.cv.pack()
self.img = tkinter.PhotoImage(file="Python.png")
self.cv.create_image(0, 0, image=self.img, anchor="nw")


root = tkinter.Tk()
app = MyApp(root)
app.mainloop()

Re: Problem mit tkinter.PhotoImage

Verfasst: Freitag 12. Mai 2023, 06:56
von Dennis89
Hallo,

ich versuche gerade herauszufinden, was du für Probleme mit dem Code hast. Wenn ich den, mit einem beliebigen *.png - Bild, laufen lasse, dann erhalte ich keine Fehlermeldung und das Bild wird angezeigt.

Was bekommst du denn für eine (vollständige) Fehlermeldung? Oder was ist nicht so, wie du es gerne hättest?

Grüße
Dennis

Re: Problem mit tkinter.PhotoImage

Verfasst: Freitag 12. Mai 2023, 07:39
von __deets__
Bitte Code in den dafür vorgesehenen Code Tags posten, damit die in Python relevanten Einrückungen erhalten bleiben.

Zu deinem Problem: es wird trotzdem ein Pfad-Problem sein. Mit

Code: Alles auswählen

import pathlib

PATH = “Bild.png”

assert pathlib.Path(PATH).exists()
muss durchlaufen. Vorher kann PhotoImage nicht Hexen.

Re: Problem mit tkinter.PhotoImage

Verfasst: Freitag 12. Mai 2023, 08:23
von Sirius3
tkinter wird üblicherweise als tk abgekürzt. Ein Frame sollte sich nicht selbst im übergeordneten Widget platzieren. Es sollte eine main-Funktion geben. Variablennamen sollte man nicht abkürzen.
Ein My-Präfix ist sinnlos, weil es keinen Mehrwert bietet, kann also weg. Tkinter definiert einige Konstanten, die man nutzen sollte.

Du gibst den Pfad zum Bild relativ zum aktuellen Arbeitsverzeichnis an. Wahrscheinlich ist es nicht das Verzeichnis, in dem das Bild liegt. Üblicherweise gibt man Pfade, die hart im Code stehen, relativ zur Python-Datei an, und legt diese Dateien auch dann passend dazu ab.

Code: Alles auswählen

import tkinter as tk
from pathlib import Path

class App(tk.Frame):
    def __init__(self, master):
        super().__init__(master)
        self.canvas = tk.Canvas(self, width=800, height=600)
        self.canvas .pack()
        self.image = tk.PhotoImage(file=Path(__file__).parent / "Python.png")
        self.canvas .create_image(0, 0, image=self.image, anchor=tk.NW)

def main():
    root = tk.Tk()
    app = App(root)
    app.pack()
    app.mainloop()

if __name__ == "__main__":
    main()

Re: Problem mit tkinter.PhotoImage

Verfasst: Freitag 12. Mai 2023, 13:32
von NinoBaumann
Sirius3 hat geschrieben: Freitag 12. Mai 2023, 08:23 tkinter wird üblicherweise als tk abgekürzt. Ein Frame sollte sich nicht selbst im übergeordneten Widget platzieren. Es sollte eine main-Funktion geben. Variablennamen sollte man nicht abkürzen.
Ein My-Präfix ist sinnlos, weil es keinen Mehrwert bietet, kann also weg. Tkinter definiert einige Konstanten, die man nutzen sollte.

Du gibst den Pfad zum Bild relativ zum aktuellen Arbeitsverzeichnis an. Wahrscheinlich ist es nicht das Verzeichnis, in dem das Bild liegt. Üblicherweise gibt man Pfade, die hart im Code stehen, relativ zur Python-Datei an, und legt diese Dateien auch dann passend dazu ab.

Code: Alles auswählen

import tkinter as tk
from pathlib import Path

class App(tk.Frame):
    def __init__(self, master):
        super().__init__(master)
        self.canvas = tk.Canvas(self, width=800, height=600)
        self.canvas .pack()
        self.image = tk.PhotoImage(file=Path(__file__).parent / "Python.png")
        self.canvas .create_image(0, 0, image=self.image, anchor=tk.NW)

def main():
    root = tk.Tk()
    app = App(root)
    app.pack()
    app.mainloop()

if __name__ == "__main__":
    main()
Hallo Sirus3,

wenn ich den Code anwende wird nur ein Ausschnitt des Bildes dargestellt. Wieso wird das Bild nicht auf die im Code angegebene Größe skaliert?

VG
Nino

Re: Problem mit tkinter.PhotoImage

Verfasst: Freitag 12. Mai 2023, 13:46
von __deets__
Warum denkst du das sollte passieren?

Re: Problem mit tkinter.PhotoImage

Verfasst: Freitag 12. Mai 2023, 14:52
von NinoBaumann
__deets__ hat geschrieben: Freitag 12. Mai 2023, 13:46 Warum denkst du das sollte passieren?
Weil ich es mit einem Bild getestet habe. Wenn ich die Größe ändere sehe ich mehr vom Bild. Demnach muss es in irgendeiner Weise einen Ausschnitt zeigen.

Re: Problem mit tkinter.PhotoImage

Verfasst: Freitag 12. Mai 2023, 16:20
von __blackjack__
@NinoBaumann: Das beantwortet nicht wirklich die Frage warum Du denkst es sollte auf den sichtbaren Bereich skaliert werden. Wird es halt nicht. Würde es das, müsste es ja auch einen dokumentierten Weg geben das *nicht* zu skalieren, wenn man das nicht haben will.

Re: Problem mit tkinter.PhotoImage

Verfasst: Freitag 12. Mai 2023, 18:52
von DerBotaniker
Sirius3 hat geschrieben: Freitag 12. Mai 2023, 08:23 tkinter wird üblicherweise als tk abgekürzt. Ein Frame sollte sich nicht selbst im übergeordneten Widget platzieren. Es sollte eine main-Funktion geben. Variablennamen sollte man nicht abkürzen.
Ein My-Präfix ist sinnlos, weil es keinen Mehrwert bietet, kann also weg. Tkinter definiert einige Konstanten, die man nutzen sollte.

Du gibst den Pfad zum Bild relativ zum aktuellen Arbeitsverzeichnis an. Wahrscheinlich ist es nicht das Verzeichnis, in dem das Bild liegt. Üblicherweise gibt man Pfade, die hart im Code stehen, relativ zur Python-Datei an, und legt diese Dateien auch dann passend dazu ab.

Code: Alles auswählen

import tkinter as tk
from pathlib import Path

class App(tk.Frame):
    def __init__(self, master):
        super().__init__(master)
        self.canvas = tk.Canvas(self, width=800, height=600)
        self.canvas .pack()
        self.image = tk.PhotoImage(file=Path(__file__).parent / "Python.png")
        self.canvas .create_image(0, 0, image=self.image, anchor=tk.NW)

def main():
    root = tk.Tk()
    app = App(root)
    app.pack()
    app.mainloop()

if __name__ == "__main__":
    main()
Das funktioniert. Vielen Dank dafür!

Um nun das Bild auf die Größe des Canvas zu reduzieren, müsste ich die resize-Option von pillow nutzen. Ich habe im Folgenden einen Code eingefügt, der genau das machen soll. Bloß werde ich mal wieder damit gestraft, dass sich mein Programm damit nicht öffnen lässt...

Code: Alles auswählen

import tkinter as tk
from PIL import Image, ImageTk 
from pathlib import Path

class App(tk.Frame):
    def __init__(self, master):
        super().__init__(master)
        self.canvas = tk.Canvas(self, width=800, height=800)
        self.canvas.pack()
        self.bild = Image.open(file=Path(r"C:\Users\xyz\Downloads\Python.png").parent/"Python.png")
        self.bild_verändert= self.bild.resize(width=800, height=800, Image.ANTIALIAS)
        self.bild_neu= ImageTk.PhotoImage(self.bild_verändert)
        self.canvas.create_image(0, 0, anchor="nw", image=self.bild_neu)


def main():
    root = tk.Tk()
    app = App(root)
    app.pack()
    app.mainloop()

if __name__ == "__main__":
    main()

Re: Problem mit tkinter.PhotoImage

Verfasst: Freitag 12. Mai 2023, 19:05
von Axel-WAK
Geht es so?

Code: Alles auswählen

        self.bild = Image.open(r"C:\Users\xyz\Downloads\Python.png")
        self.bild_verändert= self.bild.resize([800, 800], Image.ANTIALIAS)

Re: Problem mit tkinter.PhotoImage

Verfasst: Freitag 12. Mai 2023, 19:31
von DerBotaniker
Axel-WAK hat geschrieben: Freitag 12. Mai 2023, 19:05 Geht es so?

Code: Alles auswählen

        self.bild = Image.open(r"C:\Users\xyz\Downloads\Python.png")
        self.bild_verändert= self.bild.resize([800, 800], Image.ANTIALIAS)
Leider auch nicht.

Re: Problem mit tkinter.PhotoImage

Verfasst: Freitag 12. Mai 2023, 21:35
von Axel-WAK
Fehlermeldungen wären vielleicht hifreich.

Gibt es die Datei C:\Users\xyz\Downloads\Python.png überhaupt.

Bei mir funktioniert das mit einer existierenden Datei.

Re: Problem mit tkinter.PhotoImage

Verfasst: Montag 15. Mai 2023, 07:32
von DerBotaniker
Es war immer noch ein Pfadproblem, das ich aber schlussendlich lösen konnte. Vielen Dank für die hilfreichen Ratschläge!

Re: Problem mit tkinter.PhotoImage

Verfasst: Montag 15. Mai 2023, 13:39
von NinoBaumann
DerBotaniker hat geschrieben: Montag 15. Mai 2023, 07:32 Es war immer noch ein Pfadproblem, das ich aber schlussendlich lösen konnte. Vielen Dank für die hilfreichen Ratschläge!
Wenn man eine Lösung findet dann schreibt man diese auch normalerweise in den Beitrag rein damit andere mit demselben Problem eine Lösung haben.

Re: Problem mit tkinter.PhotoImage

Verfasst: Dienstag 16. Mai 2023, 07:53
von DerBotaniker
NinoBaumann hat geschrieben: Montag 15. Mai 2023, 13:39
DerBotaniker hat geschrieben: Montag 15. Mai 2023, 07:32 Es war immer noch ein Pfadproblem, das ich aber schlussendlich lösen konnte. Vielen Dank für die hilfreichen Ratschläge!
Wenn man eine Lösung findet dann schreibt man diese auch normalerweise in den Beitrag rein damit andere mit demselben Problem eine Lösung haben.
Die Lösung wurde bereits weiter oben angesprochen. Mein Bild befand sich bloß im falschen Ordner. Nachdem ich es parallel zum Python-Arbeitsverzeichnis angelegt hatte lief alles gut.