Hatayı ImageTk.PhotoImage'in resize fonksiyonu olmadığı için alıyorsunuz. Image.open(file) nesnesinin resize fonksiyonu var.
Sizinle paylaşılan kodu okuyarak hangi satırda ne var anlayarak yazmanız lazım. Aldığınız hatayı neden aldığınızı fark etmiyor olmanız, yazılan kodu gerçekte anlamadığınız anlamına geliyor. O yüzden daha fazla ileri gitmeden önce şu ana kadar geldiğiniz yere kadar olan kısımları sindirmeye çalışın bence.
Değil, aynı işlemler yapılıyor. Hatta benim yazdığım sınıf, canvas nesnesinin daha fazla özelleştirilmesini sağlıyor. Özelleştirmekten kastım, resim küçültülecek mi yoksa olduğu gibi mi duracak, bunlara imkan veriyor. Kod kısaltma hadisesini bir zorunluluk gibi görmeyin. Kısaltabiliyorsanız kodu kısaltın ancak neyi kısalttığınızı ve işlemlere olan etkisini de bilin. Yukarıdaki sınıfı kaldırın, isterseniz fonksiyon kullanın, ama istediğiniz gibi çalışması için yazmanız gereken kodu fonksiyonda da yazacaksınız, sınıfta da yazacaksınız. Değişen bir şey olmayacak.
@EkremDincel orada yanlış bir şey söylemedi. Siz rastgele değişkenler oluşturmak isteyince ben de size başka bir yaklaşım daha gösterdim. Normalde global alanda bir liste tanımlayıp, PhotoImage nesnelerini bu listede tutabilirdiniz. Bu örnekte de PhotoImage nesnelerini tutacak bir liste kullanılıyor. Ayrıca ben böyle bir örnek yapmak istesem, fonksiyon yerine sınıf kullanırım. Siz istiyorsanız fonksiyon kullanın. Bir şey diyemiyorum.
Anladım hocam peki sağ olun. Ben kesinlikle kendi bildiğim en doğrudur diyemem, sonuç olarak amatör kümede top koşturuyorum. Projemi zaten bir kaç ay önce tamamlamıştım fakat ben kodları kısaltıp daha iyi bir noktaya nasıl getirebilirim gayreti içerisindeyim ve bunu yaparken de kendi yorumumu katarak geliştirmek eğlenceli oluyor. ( Verilen örnekler için teşekkürler değerlendireceğim. )
Aslında takıldığım nokta: izlenilen yolun yanlış olmadığı konusunda hem fikir olmamız hatta kullanılabilir olarak isimlendirip sonrasında “Bakın yukarıdaki koddan vazgeçin bence” yorumu oldu.
Ayrıca belirtmek isterim ki fonksiyon yerine class yapısı çok daha mantıklı katılıyorum bu sadece bir ön izleme geliştirmeye açık bir fikir üzerine düşülse çok daha iyi bir temel olabilir.
Bir nesne oluşturmak ve bu nesnelerin parametrelere göre özelleşmesini sağlamak istediğimde, aklıma direk sınıf kullanmak gelir.
Sınıf kullanma sebeplerimi biraz açayım isterseniz.
Sınıf, nesne ile alakalı olan bütün işlemlerin, değişkenlerin sınıfın içerisinde düzgün bir şekilde yer almasını sağlar. Bir bakıma kodun okunurluğunu artırır.
Sınıf, değişkenlere sınıfın her yerinden erişebiliyor olmamızı sağlar. Eğer bir değişkenin değeri değiştirilecekse, değişkeni global hale getirmeden değerini değiştirebilirsiniz.
Sınıf, kendisinden türetilecek sınıflara bir temel sağlar. Bir kaç projemde daha sonra farklılaşacak olan ama belirli ortak yerleri olan bir çok alt sınıfın miras aldığı ebeveyn sınıflar tasarlamıştım. Alt sınıfları farklılaştırmak, onlara yeni özellikler eklemek böylece çok daha kolay ve işlevsel oluyor. Zaten bizim tk widgetlerini miras alan sınıflar tasarlamamızın ana nedenlerinden birisi de sınıfı özelleştirmek.
Bunun haricinde globals()[isim] ile sürekli değişken oluşturmak da aslında gereksiz bir karmaşıklığa neden oluyor.
Yani şunu mu tercih edersiniz?
for i in range(10):
globals()[f"entry_{i}"] = tk.Entry(master=root)
globals()[f"entry_{i}"].pack()
Yoksa şunu mu?
entries = []
for i in range(10):
entry = tk.Entry(master=root)
entry.pack()
entries += [entry]
Tamam ilk kısımda 3 satır kod yazdık, ikincisinde 5 satır. Ama bir de bu entrilere ulaşmak söz konusu olduğunda, birinde globals’de entry arayacaksınız, diğerinde entries listesini kullanacaksınız.
Diyelim bu entrilere ulaşmak için şöyle bir fonksiyon yazdınız:
def get_entries():
return [
v for k, v in globals().items()
if isinstance(v, tk.Entry) and k.startswith("entry")
]
Bu fonksiyondan dönen değeri de entries isimli bir değişkene atadınız diyelim. E peki bunca zahmete girmeden, widgetler oluşturulurken entries tanımlansaydı daha az işlem yapılmış olmaz mıydı? Gördüğünüz gibi entrilerin hepsine ulaşmak istediğimiz zaman ikinci bir for döngüsü kurmak, globals()'i yani entries’den daha büyük bir veriyi taramak zorunda kaldık.
Peki diyelim ki liste yapısını kullanıyoruz en son attığım örnekten yola çıkarak baktığımızda change_image fonksiyonu içerisine bir önceki resmi listeden silerek yerine değiştirilecek resmi ekleyerek mi ilerlemek doğru olur.
Eğer bir resim değiştirilecek yerine yenisi gelecek ve eski resim bir daha kullanılmayacak ise değiştirme işleminde eski resmi silmek gerekir. Ama bunu yaparken bir koşul da tanımlamalısınız, çünkü zaten listeden silinmiş olan bir değişkeni tekrar silmeye kalkarsanız hata alırsınız. Ama eğer resim değiştikten sonra eski resim tekrar kullanılacaksa silmenin bir anlamı yok. Resimlere ulaşmak için listenin indislerini kullanabilirsiniz. İndis ile uğraşmak istemiyorum, anahtar sözcükler kullanarak resimlere ulaşmak istiyorum diyorsanız, bu kez de sözlük kullanabilirsiniz.