Bild mit Canvas anzeigen

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
RolandKM
User
Beiträge: 25
Registriert: Montag 21. Dezember 2020, 10:20

Hallo,

ich möchte in einem Fenster ein Bild anzeigen, das im gleichen Verzeichnis wie die Python-Datei steht, bekomme aber die Meldung "_tkinter.TclError: image "pyimage1" doesn't exist".
Wer kann helfen ?

Code: Alles auswählen

from tkinter import *

fenster1=Tk()
fenster2=Tk()
fenster1.title("Mein Fenster 1")
fenster2.title("Mein Fenster 2")

def start_action():
    canvas2 = Canvas(fenster2, width=100, height=100)
    canvas2.pack()
    myimage = PhotoImage(file="bild.png")
    canvas2.create_image(0, 0, anchor="sw", image=myimage)

canvas1 = Canvas(fenster1,width=400,height=350)
canvas1.pack()
canvas1.create_line(0,50,400,50,fill="red")
canvas1.create_text(100,100,text="Testzeile")
start_button = Button(fenster1,text="Start", command=start_action)
start_button.place(x=50,y=300,width=80,height=30)
exit_button = Button(fenster1, text="Beenden", command=fenster1.quit)
exit_button.place(x=250,y=300,width=80,height=30)

fenster1.mainloop()
__deets__
User
Beiträge: 14545
Registriert: Mittwoch 14. Oktober 2015, 14:29

Top 5 der tkinter Probleme. Du musst eine eigene Referenz auf das PhotoImage Objekt festhalten. Das wird sonst abgeräumt von garbage collector. Wird hier öfter diskutiert, such mal danach. Am besten via Google.
RolandKM
User
Beiträge: 25
Registriert: Montag 21. Dezember 2020, 10:20

Kannst Du das mal näher erläutern (Beispiel) ? Trotz Durchsuchen zahlreicher Forenbeiträge bin ich nicht schlauer geworden.
Eine Anzeige des Bildes im "fenster1" klappt ja, aber nicht im "fenster2" !
__deets__
User
Beiträge: 14545
Registriert: Mittwoch 14. Oktober 2015, 14:29

Ich sehe gerade du hast noch einen ganz anderen, sehr viel gröberen, Fehler: man darf kein Tk Objekt zweimal erstellen. Davon darf immer nur eines existieren. Das zweite Fenster muss ein Toplevel-Fenster sein.

Und hier eine Diskussion des ersten Problems: viewtopic.php?t=47387
RolandKM
User
Beiträge: 25
Registriert: Montag 21. Dezember 2020, 10:20

Da wird "PIL" verwendet. Ich habe gelesen, dass man für PNG-Bilder das nicht braucht (sondern nur bei JPG). Ist das richtig ?
Wie wird denn die Referenz auf das Bild festgehalten. Kannst Du mal ein Beispiel geben ?
__deets__
User
Beiträge: 14545
Registriert: Mittwoch 14. Oktober 2015, 14:29

Schau doch mal in den Code. Da steht das drin. Blackjack beschreibt das. Und macht es vor. Ein bisschen Selbststudium statt vorgekaute Happen zu verlangen darfs schon sein.

Und wenn deine Anwendung PIL nicht braucht, lass es weg. Das ändert dein Problem aber nicht.
RolandKM
User
Beiträge: 25
Registriert: Montag 21. Dezember 2020, 10:20

Den Fehler bzgl. zweites Tk-Objekt habe ich verstanden und korrigiert.
Ob ich das mit dem "Binden" habe ich wohl noch immer nicht durchschaut
Das Script läuft jetzt (siehe Code). Es funktioniert aber sowohl mit

canvas2.create_image(0,0,anchor="nw",image=copyimage) als auch mit
canvas2.create_image(0,0,anchor="nw",image=myimage)

Code: Alles auswählen

from tkinter import *

fenster=Tk()
fenster.title("Mein Fenster 1")

def start_action():
    fenster2=Toplevel()
    canvas2 = Canvas(fenster2, width=500, height=500)
    canvas2.pack()
    myimage = PhotoImage(file="bild.png")
    copyimage = myimage.copy()
    canvas2.create_image(0,0,anchor="nw",image=copyimage)
    fenster2.mainloop()

canvas1 = Canvas(fenster,width=400,height=350)
canvas1.pack()
canvas1.create_line(0,50,400,50,fill="red")
canvas1.create_text(100,100,text="Testzeile")
start_button = Button(fenster,text="Start", command=start_action)
start_button.place(x=50,y=300,width=80,height=30)
exit_button = Button(fenster, text="Beenden", command=fenster.quit)
exit_button.place(x=250,y=300,width=80,height=30)

fenster.mainloop()
Nach dem Schließen des Fensters2 muss ich aber im Fenster1 2x auf "Beenden" klicken !?

Vielleicht hat einer von Euch noch einen Tipp ?
__deets__
User
Beiträge: 14545
Registriert: Mittwoch 14. Oktober 2015, 14:29

Das ist doch alles geraten. Nirgendwo in dem von mir zitierten Beispiel steht copy.

In blackjacks code gibt es eine Funktion mit 3(!) Zeilen, die mit einem PhotoImage hantieren. 2 davon sind nahezu gleich mit dem, was du tust. Eine macht etwas anderes. Das ist ein ganz heißer Kandidat für etwas, das auch du machen musst.

Und mainloop ruft man genau einmal auf. Alles was du so jetzt erreicht hast, ist die lokalen Namen leben zu lassen. Aber das ist keine erfolgreiche Strategie, weil du damit deinen Interpreter-Stack bestenfalls unnötig vergrößerst, schlimmstenfalls Fehler provozierst. Wie zb x-mal beenden klicken zu müssen.
RolandKM
User
Beiträge: 25
Registriert: Montag 21. Dezember 2020, 10:20

Danke "__deets__" für Deine Hinweise, irgendwie hast Du schon Recht.
Ich will hier nicht rumjammern, aber: Mit knapp 60 Lenzen, Kenntnissen auf "Turbo Pascal Niveau", Arbeit im öffentl. Dienst ("wir programmieren hier nichts") ist die Sache nicht ganz so einfach. Da versucht man sich im Home Office doch mal an was Neuem (Python, weil auf allen Rechnern durch andere Software).
Aber ich versuche es trotzdem und werde mein Beispiel noch mal neu angehen. :?
__deets__
User
Beiträge: 14545
Registriert: Mittwoch 14. Oktober 2015, 14:29

Du wirst das schon schaffen. Es gibt eben nur Dinge, die ein bisschen mehr Verständnis brauchen, mehr Auseinandersetzung. Und nicht einfach nur mit Prokelei zu wuppen sind. GUIs gehören definitiv dazu.
Antworten