Canvas: Eklediğim bir önceki resimler gözükmüyor

Merhaba iyi geceler, aşağıdaki kodda göreceğiniz üzere nesne tabanlı bir çalışma yapıyorum fakat bir problem ile karşılaştım eklediğim canvas resimlerin sadece sonuncusu gözüküyor problemin çözümünü biliyorsanız yardımcı olursanız sevinirim.

KOD:

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


# NESNE TABANLI DENEME
def create_image(canvas,file):
    img = Image.open(file)
    images = ImageTk.PhotoImage(img)
    canvas.images = images
    return images


def create_canvas_img(canvas,file,x,y):
    canvas.create_image(x,y,image=create_image(canvas,file), anchor="nw",tag="button")


root = tk.Tk()
root.geometry("400x400")
canvas = tk.Canvas(master=root,width=500,height=500,bg="green")
canvas.pack()
create_canvas_img(canvas=canvas,file=r"resimler\arkaplan.png",x=10,y=50)
create_canvas_img(canvas=canvas,file=r"resimler\refresh.png",x=60,y=150)
create_canvas_img(canvas=canvas,file=r"resimler\refresh_hover.png",x=120,y=150)
root.mainloop()

PROBLEM
image

Bunun sebebi, canvas.images'in sürekli yeni bir değer alması. canvas.images'i bir list haline getirin, oluşturulacak resimler de bu listeye eklensinler.

Kodlar:

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


# NESNE TABANLI DENEME
def create_image(canvas,file):
    img = Image.open(file)
    images = ImageTk.PhotoImage(img)
    canvas.images += [images]
    return images


def create_canvas_img(canvas,file,x,y):
    canvas.create_image(x,y,image=create_image(canvas,file), anchor="nw",tag="button")


root = tk.Tk()
root.geometry("400x400")
canvas = tk.Canvas(master=root,width=500,height=500,bg="green")
canvas.images = []
canvas.pack()
create_canvas_img(canvas=canvas,file=r"resimler\arkaplan.png",x=10,y=50)
create_canvas_img(canvas=canvas,file=r"resimler\refresh.png",x=60,y=150)
create_canvas_img(canvas=canvas,file=r"resimler\refresh_hover.png",x=120,y=150)
root.mainloop()
1 Beğeni

List vs. kullanmadan resim eklemenin farklı ve kolay bir yolu var mı acaba ?

Var, evet. ImageTk.PhotoImage nesnelerini global alanda tanımlayabilirsiniz. Veya bir önceki mesajımda önerdiğim yaklaşımı da izleyebilirsiniz. İlla canvas.images gibi aslında canvas'a ait olmayan bir attribute oluşturmak zorunda değilsiniz. Herhangi bir boş liste kullansanız da olur. Veya tk.Canvas nesnesini özelleştirip, bu özelleştirilmiş nesnenin, ImageTk.PhotoImage nesnelerini içermesi için kullanılacak bir attribute da tanımlayabilirsiniz. Size kalmış. Amaç, ImageTk.PhotoImage nesnesi bir fonksiyon veya bir sınıf içinde yer alan local bir değişkenin değeri olduğunda, global alanda yer alan bir başka değişkenin değerinin, bu local değişkenin değerini içermesini, ona değinmesini sağlamak ve böylece nesnenin garbage collector'a gitmesini önlemek.

1 Beğeni

Aslında değişkenleri rastgele isimlendirebilsek her seferinde bu şekilde olabilirdi.

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


def get_random_string(length):
    sample_letters = 'abcdefghi'
    result_str = ''.join((random.choice(sample_letters) for i in range(length)))
    print("String:", result_str)

def img_creator(file):
    attribute = get_random_string(5)
    attribute = Image.open(file)
    attribute = ImageTk.PhotoImage(attribute)
    canvas.create_image(0, 0, image=attribute, anchor="nw")
    canvas.image = attribute


root = tk.Tk()
root.geometry("400x400")
canvas = tk.Canvas(master=root,width=500,height=500,bg="green")
canvas.pack()

img_creator(file="resimler\\arkaplan.png")
img_creator(file="resimler\\kapat.png")


root.mainloop()

canvas.image = attribute dedikten sonra istediğiniz kadar farklı isimlerde değişkenler oluşturun, bir önceki images değişkeninin tuttuğu değer değişecek.

İlla farklı değişken isimleri kullanmak istiyorsanız, canvas.image'i silersiniz ve her bir resim için random isimleri şu şekilde oluşturabilirsiniz.

def img_creator(file):
    string = get_random_string(length=10)
    globals()[string] = ImageTk.PhotoImage(Image.open(file))
    canvas.create_image(0, 0, image=globals()[string], anchor="nw")

Not: get_random_string fonksiyonunun bir string döndürmesi gerekiyor.

1 Beğeni

Ama sonucu etkilemedi :frowning:

Nasıl bir kod yazdınız?

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


def get_random_string(length):
    sample_letters = 'abcdefghi'
    result_str = ''.join((random.choice(sample_letters) for i in range(length)))
    print("String:", result_str)

def img_creator(file):
    string = get_random_string(length=10)
    globals()[string] = ImageTk.PhotoImage(Image.open(file))
    canvas.create_image(0, 0, image=globals()[string], anchor="nw")


root = tk.Tk()
root.geometry("400x400")
canvas = tk.Canvas(master=root,width=500,height=500,bg="green")
canvas.pack()

img_creator(file="resimler\\arkaplan.png")
img_creator(file="resimler\\kapat.png")


root.mainloop()

Size bir önceki mesajda get_random_string bir değer döndürsün demiştim. Ama siz bir değer döndürmemişsiniz. Bu yüzden string hep "None" oluyor.

1 Beğeni

Return eklememişim pardon :slight_smile:. Fikir işlevsel değil mi peki sizce.

Kullanabilirsiniz bu yöntemi de. Bu da ImageTk.PhotoImage nesnelerini bir şekilde global yapmak demek zaten.

1 Beğeni

Daha özgün olması bana cazip geliyor ondan dolayı farklı bir yol arayışındayım.

Naçizane düşüncem şöyle; böyle de yapsanız olur, öyle de yapsanız olur. Nasıl istiyorsanız öyle yapın.

1 Beğeni

Ayrıca hocam sizinle fikir alışverişi yapmak daha keyifli oluyor çayımı kahvemi alıp samimiyetle kodluyorum :slight_smile:

Güzel sözleriniz için teşekkür ederim. Yardımım dokunuyorsa ne mutlu bana. :slight_smile:

1 Beğeni

Fazlasıyla oldu teşekkürler, geceniz güzel olsun. :wave:

1 Beğeni

Sizin de geceniz güzel olsun. İyi çalışmalar.

1 Beğeni

Yok. Resimlerin bir yerde saklanması lazım.

Oluşturulan resimlerin bir listede toplanması yeterince kolay değil mi?


@dildeolupbiten global isim alanını rastgele değişkenler ile kirletmeyi bir çözüm olarak sunmanızı doğru bulmuyorum. Böyle bir kodu birisinin projesinde kullanmasını ister miydiniz?

Ben arkadaşa izleyebileceği yöntemler konusunda bir çeşitlilik sundum. global alanda rastgele değişkenler oluşturmasını özellikle tavsiye etmedim.

şeklinde bir cevap geldikten sonra.

Yukarıdaki gibi bir yazı yazdım.

Konuyla alakalı görüşümü de şu şekilde ifade ettim.

Yani hangi yaklaşımın daha doğru olacağı konusunda herhangi bir görüş beyan etmek istemedim. Sadece yolları gösterdim, arkadaş hangi yolu tercih etmek istiyorsa onu kullansın dedim.