Tkinter Canvas Image lässt sich nicht wiederherstellen

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

Huhu,
Ich beschäftige mich derzeit bei den GUIs mit Hintergründen durch Canvas. Um einen Hintergrund zu erstellen, gebe ich folgendes ein (klappt einwandfrei):

Code: Alles auswählen


    pil_background_image = Image.open("TestFile.jpg")
    fenster.tk_background_image = ImageTk.PhotoImage(pil_background_image)

    width = fenster.tk_background_image.width()
    height = fenster.tk_background_image.height()

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

    Logo = canvas.create_image(0, 0, image=fenster.tk_background_image, anchor="nw", tag="Hintergrund")
Wenn ich versuche, via Knopfdruck den Hintergrund zu ändern, gebe ich ein:

Code: Alles auswählen

def Clear():
	Clear_button.config(command=Clear_back)
        canvas.delete(Logo)
        pil_background_image2 = Image.open("TestFileNeu.jpg")
        fenster.tk_background_image = ImageTk.PhotoImage(pil_background_image2)
        width = fenster.tk_background_image.width()
        height = fenster.tk_background_image.height()
        canvas2 = tk.Canvas(fenster, width=width, height=height, highlightthickness=0)
        canvas2.pack()
        Logo2 = canvas.create_image(0, 0, image=fenster.tk_background_image, anchor="nw", tag="Hintergrund")
        Clear_button = Button(fenster, text="Clear", command=Clear)
        canvas.create_window(30,20, window=Clear_button, anchor="nw")
Klappt auch. wenn ich jetzt aber versuche, den Hinbtergrund wiederzurückzuändern:

Code: Alles auswählen

def Clear_back():
        Clear_button.config(command=Clear)
        pil_background_image = Image.open("TestFile.jpg")
        fenster.tk_background_image = ImageTk.PhotoImage(pil_background_image)

    	width = fenster.tk_background_image.width()
    	height = fenster.tk_background_image.height()

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

   	 Logo = canvas.create_image(0, 0, image=fenster.tk_background_image, anchor="nw", tag="Hintergrund")
Dann löscht sich der Hintergrund "TestFile2", also der 2., aber der 1. erscheint nicht wieder, sondern das ganze Canvas-Hintergrund Zeugs verschwindet und der Default Tkinter Hintergrund kommt... Weiß wer, wie man das richtig macht, bzw ob es eine Art "Canvas.config" gibt?

Vielen Dank schonmal im Voraus!
Mir egal, ob der Code schön ist oder nicht.
Hauptsache er funkt!
Benutzeravatar
__blackjack__
User
Beiträge: 13004
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

Das sieht alles recht wirr aus. Es scheint Code auf Modulebene zu geben und die Funktionen greifen auf ”magische” Weise auf Objekte zurück die keine Konstanten sind, aber auch nicht als Argumente übergeben werden. Und bei GUIs braucht man eigentlich fast immer objektorientierte Programmierung, also eigene Klassen, um das sauber und nachvollziehbar zu machen.

Du erstellst auch bei jedem Knopfdruck immer mehr und mehr Widgets im Fenster, was nicht zu der Beschreibung passt, das da ein Canvas geändert werden soll‽ Normalerweise erstellt man die Anzeigeelemente alle am Anfang *einmal* und verändert sie dann im Laufe des Programms entsprechend und erzeugt nicht ständig neue Widgets die dem Fenster hinzugefügt werden.

Es gibt eine `Canvas.config()` -Methode, aber Du willst ja eher die `Canvas.itemconfig()`-Methode wenn Du Elemente auf dem Canvas umkonfigurieren möchtest.
“Most people find the concept of programming obvious, but the doing impossible.” — Alan J. Perlis
Phobit
User
Beiträge: 185
Registriert: Freitag 4. Mai 2018, 18:13

Das es wirr ist mag sein, den "Paradecode" auf dem basierend ich den hier geschrieben habe stammt aus diesem Forum...


Wie sähe der itemconfig dann aus, wenn ich einfach nur den Hintergrund aus TestFIle zurückändern möchte, wie oben beschreiben?
Mir egal, ob der Code schön ist oder nicht.
Hauptsache er funkt!
Benutzeravatar
__blackjack__
User
Beiträge: 13004
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

Code: Alles auswählen

#!/usr/bin/env python
# coding: utf-8
from __future__ import absolute_import, division, print_function
import Tkinter as tk
from functools import partial
from itertools import cycle
from PIL import Image, ImageTk


def next_image(canvas, item_id, images):
    image = next(images)
    canvas.config(width=image.width(), height=image.height())
    canvas.itemconfig(item_id, image=image)


def main():
    root = tk.Tk()
    
    images = cycle(
        ImageTk.PhotoImage(Image.open(filename))
        for filename in ['test.png', 'test2.png']
    )
    
    canvas = tk.Canvas(root, highlightthickness=0)
    canvas.pack()
    background = canvas.create_image(0, 0, anchor=tk.NW)
    
    button = tk.Button(
        root,
        text='Next',
        command=partial(next_image, canvas, background, images),
    )
    button.pack()
    button.invoke()
    
    root.mainloop()


if __name__ == '__main__':
    main()
“Most people find the concept of programming obvious, but the doing impossible.” — Alan J. Perlis
Phobit
User
Beiträge: 185
Registriert: Freitag 4. Mai 2018, 18:13

Nicht böse gemeint, aber einfacher gehts nicht irgendwie XD?
Ohne Canvas Images gehts auch in 2-3 Zeilchen...
Mir egal, ob der Code schön ist oder nicht.
Hauptsache er funkt!
Benutzeravatar
__blackjack__
User
Beiträge: 13004
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

Das ist schon so einfach wie's geht ohne unsauber zu werden. Was denkst Du denn was davon nicht gebraucht wird für ein *komplettes* und *lauffägiges* Beispiel? Dein Code ist auch nicht weniger und ist noch nicht einmal ein komplett lauffähiges Beispiel des Problems.
“Most people find the concept of programming obvious, but the doing impossible.” — Alan J. Perlis
Phobit
User
Beiträge: 185
Registriert: Freitag 4. Mai 2018, 18:13

Ja, habe das Programm auch allgemein einfach geschrieben, da ich nicht die Kenntnisse habe um alles aufwendig, aber einfach, zu machen. Solange es auf diese Art klappt...?
Mir egal, ob der Code schön ist oder nicht.
Hauptsache er funkt!
Antworten