Def içerisindeki resimleri butona eklemek

Merhaba, aşağıdaki kodda görülecegi üzere images def’i içerisindeki resimi butonda çalıştırmak istiyorum bunu yapmanın bir yolu varmı ?


def images(name=None):
    from PIL import Image, ImageTk, ImageOps
    res = Image.open("images/uyarı_2.png").resize((35, 35))
    resim = ImageTk.PhotoImage(res)
    name["image"] = resim

if __name__ == '__main__':
    from tkinter import *
    root = Tk()
    root.geometry("500x500")
    btn = Button(root,text="Test",width=20,bg="green",image=images(btn))
    btn.pack(side=BOTTOM,pady=50)
    root.mainloop()

HATA:

Traceback (most recent call last):
  File "C:/Users/user/Desktop/Python/deneme.py", line 12, in <module>
    btn = Button(root,text="Test",width=20,bg="green",image=deneme(btn))
NameError: name 'btn' is not defined

Merhaba,

btn değişkeni tanımlanmadan, btn değişken ismini images fonksiyonuna parametre olarak verdiğiniz için hata alıyorsunuz. Önce btn değişkeni tanımlanmalı, daha sonra değişkenin değeri olan Button nesnesinin image anahtarının değeri oluşturulmalı.

Ayrıca from tkinter import * şeklinde yazılmış bir import deyimi, kullanmayacağınız nesneleri de programa aktarır. Genellikle import deyiminin bu şekilde kullanımı pek tavsiye edilmez.

Şayet images fonksiyonu bir çok kere çağrılmayacak ise, PIL kütüphanesinin modüllerini fonksiyon içerisinde import edebilirsiniz. Ama images fonksiyonu birçok kez çağrılacaksa, o zaman import edilen modüller bir çok kez gereksiz yere import edilirler.

if __name__ == "__main__": blokundaki kodu daha kısa tutmanızı öneririm. Örneğin, o bloktaki kodu alıp, main() isimli bir fonksiyona dahil edebilir ve main() fonksiyonunu da if __name__ == "__main__": blokunda çağırabilirsiniz.

2 Beğeni

Öneriler için teşekkürler if name == “main”: bölümündeki kodları uzun tutmanın ne gibi bir sakıncası var ? kodları geliştirip daha iyi bir yola çıktığımı düşünüyorum ama bu sefer farklı bir sorun ile karşılaştım sadece son eklediğim butonda resim gözüküyor.


import tkinter as tk

class SampleApp(tk.Tk):
    def __init__(self,x,y,name=None):
        from PIL import Image, ImageTk, ImageOps
        global resim
        btn = tk.Button(root,text=f"{name}",width=20,bg="green")
        btn.place(x=x,y=y)
        res = Image.open("images/uyarı_2.png").resize((50, 50))
        resim = ImageTk.PhotoImage(res)
        btn["image"] = resim





if __name__ == '__main__':

    root = tk.Tk()
    root.geometry("500x500")
    SampleApp(x=180,y=150)
    SampleApp(x=50,y=20)
    SampleApp(x=250,y=20)
    root.mainloop()

Programlama açısından herhangi bir sakıncası yok, sadece görsel olarak daha okunaksız. Gerçi, bu da öznel bir değerlendirme. İsterseniz uzun tutabilirsiniz tabi.

Sebebi global ifadesinden kaynaklanıyor. global resim satırını silin, resim değişkenini tanımladıktan sonra, btn.resim = resim satırını yazın. Artık oluşan bütün nesnelerde resimler görünecektir.

1 Beğeni

Bu arada son paylaştığınız kodda, PIL kütüphanesi nesne yapıcı fonksiyona yazılmış. Bu durumda, yazdığınız koda göre, from PIL import Image, ImageTk, ImageOps satırı oluşturduğunuz nesne sayısı kadar çalıştırılır. İlk mesajımda bahsettiğim hususlardan birisi buydu. En iyisi bu import deyimini global alana taşımak.

1 Beğeni

Aaa, evet gözden kaçmış teşekkürler :slight_smile: