Otomatik olarak belirli sayıda widget oluşturmak?

Örneğin bir klasördeki dosyaları listeleyecek ve kullanıcıya sunacağım. Listede her dosyanın yanına bir de “Görüntüle” butonu eklemek istiyorum. Ama buton miktarı haliyle belirli olmayacak. Buton sayısını listeleme anında sayaç sistemi ile belirleyebilirim tabi ki. Ama sonraki adımlar kafamı kurcalıyor. Ne önerirsiniz?

Şimdiden teşekkürler…

Aslında buraya kod yazımında geldiğiniz yere kadar kodları aktarırsanız, kodlar üzerinden önerilerde bulunulabilir. Ama anladığım kadarıyla istediğiniz sayıda buton eklemek için bir for döngüsü oluşturmanız gerekiyor. For döngüsünün içinde butona özellik kazandırabilirsiniz. Eklemek istediğiniz özellik sadece ‘görüntüle’ ise, aşağıdaki gibi bir yol izlenebilir herhalde. Bu arada dosya listesinin nasıl olduğunu bilmiyorum bu yüzden temsili bir kod örneği yazdm:

from tkinter import *
import os


class Application:
    def __init__(self):
        self.window = Tk()

        self.frame_1 = Frame()
            self.frame_1.grid(row=0, column=0)

            self.widgets()
            self.mainloop = self.window.mainloop()

        def widgets(self):
            dosyalar = self.dosya_işlemleri()
            for i in range(len(dosyalar)):
                buton = Button(self.frame_1, text="buton{}".format(i), command=self.bastır(dosyalar[i]))
                buton.grid(row=0, column=i)

        @staticmethod
        def dosya_işlemleri():
            yol = "D:\\dizin\\altdizin"
            dosya_listesi = [i for i in os.listdir(yol) if os.path.isfile(os.path.join(yol, i))]
            return dosya_listesi

        @staticmethod
        def bastır(dosya):
            def yerel_print():
                print(dosya)
            return yerel_print


a = Application()

Ama başta da dediğim gibi, kodlarınız olmadan yukarıdaki yol oldukça soyut kalıyor. Yukarıda, sadece basit bir kalıp oluşturuldu. Dizin adını belirtiyorsunuz ve o dizindeki dosya kadar buton oluşturuluyor. Butonlara tıklıyorsunuz ve her buton dizindeki dosyanın ismini ekrana bastırıyor. Belki yapmak istediğiniz şeyler yukarıdaki kod yapısının belli yerlerini değiştirecek, belki daha farklı bir yöntem izlemeniz gerekecek, onu bilemiyorum. Ancak şu anda üzerinde uğraştığım çalışmadan edindiğim izlenime göre, oluşturmuş olduğunuz taslağı, o taslakla çalışacak örneklere göre yeniden düzenlemeniz gerekebilir, hatta belki taslağın farklı örneklerde de çalışabilmesi için örneklerin de taslağını oluşturabilirsiniz…

1 Beğeni

Henüz yazmaya başlamadım suan kafamda oluşturmaya çalışıyorum ki bu konuda takıldım.
Randevu kaydedip uyarı verecek bir program olacak. Görüntüle butonu ile bilgilerin text ve entry widgetlarinda verilerek düzenledikten sonra kaydedilebilecek olmasını planlıyorum. Randevular da tarih ve saat ismi ile oluşturulmuş dosyalar olacak sanırım. Herşey kafamda kolay canlanıyor ama listeleme ve butonlar kafamı karıştırdı. Tabi ki buttonlar kadar label da oluşturulacak.
Oop ye yeni başladığım icin ayrıntıları çözemiyorum. Kodlarınızı basitleştirirsiniz minnettar olurum. Teşekkürler…

Prosedürel yöntemle yukarıdaki kodlar aşağıdaki gibi olur.

from tkinter import *
import os


def dosya_işlemleri():
    yol = "D:\\dizin\\altdizin\\"
    dosya_listesi = [i for i in os.listdir(yol) if os.path.isfile(os.path.join(yol, i))]
    return dosya_listesi


def bastır(dosya):
    def yerel_print():
        print(dosya)
    return yerel_print

pencere = Tk()

çerçeve = Frame()
çerçeve.grid(row=0, column=0)

dosyalar = dosya_işlemleri()
for i in range(len(dosyalar)):
    düğme = Button(çerçeve, text="düğme{}".format(i), command=bastır(dosyalar[i]))
    düğme.grid(row=0, column=i)

pencere.mainloop()

Siz bir yazmaya başlayın, sıkıntıya düştüğünüz yerde, yardım istersiniz. Kodlar ilk etapta kafanızı karıştırabilir ancak ümitsizliğe kapılmayın. Ben de alışana kadar kafa karışıklığı yaşadım, bazı yeni durumlarda hala yaşıyorum ki gayet normal bence. Siz de alışana kadar kendinize süre verin ve nacizane tavsiyem, öğrendiğiniz şeylerle önce basit örnekler yapın, iyice pekişsin bilgiler. Sonradan çok daha fazla kod yığını gerektiren durumlarda ne yapmanız gerektiğini ve nasıl yapacağınızı daha rahat bulabilirsiniz. Şimdiden kolay gelsin.

Tesekkürler. Yerlestirme meselesi de kafami kurcalamisti ama mantigi anladim. Ve sanirim yerlestirildikten sonra her dügmeyi yeni degiskene atamak gerekmiyor. Kafamdaki takilmalar bayagi eksildi. Birkac denemeyle kendim de yazabilirim artik. Tesekkürler :slight_smile:

Yukarıdaki gibi bir for döngüsü kurarak tek seferde birden fazla buton ekleyebilirsiniz. Bu butonların yapacakları işlemler için yukarıdaki gibi bir bastır() fonksiyonu tanımlayabilirsiniz. Yukarıdaki örneğe göre bütün butonlar ilgili oldukları dosyaların adlarını ekrana bastırıyor. Bunun için de aşağıdaki fonksiyonu command kısmında çağırdık.

def bastır(dosya):
    def yerel_print():
        print(dosya)
    return yerel_print
#yerel_printi parantezli geri çağırsaydık, sayfa açılır açılmaz ekrana dosya isimleri bastırılacaktı.
command=bastır(dosyalar[i]))

Yukarıdaki fonksiyonu değilde aşağıda gösterilen fonksiyonu yazmış olsaydık, bütün butonların aynı işlemi yapmış olduğunu görürdük:

command=lambda: print(dosyalar[i]))

Aslında örnekteki bastır() fonksiyonu da her bir butonun aynı işlemi yapmasını sağlıyor, lambda fonksiyonundan farkı ise hangi dosyanın isminin ekrana bastırılacağını bastır() fonksiyonuyla seçebiliyorken, yukarıda gösterilen lambda fonksiyonuyla seçemiyoruz. bastır() fonksiyonunun içinde başka bir fonksiyon tanımlanmış olduğuna dikkat etmenizi tavsiye ediyorum. Yoksa bastır() fonksiyonu aşağıdaki gibi tanımlanmış olsaydı lambda fonksiyonuyla benzer bir işlemi yapacaktı:

def bastır():
    print("basıldı")
command=bastır

Bastır() fonksiyonunun parantezlerinin konulmadığını hatırlatmak isterim. Şayet bu parantezleri koyarsanız, pencere açılır açılmaz, buton sayısı kadar “bastır” yazısı ekrana bastırılır. Ama command=bastır(dosyalar[i])) fonksiyonumuzda parantezler olmasına rağmen, pencere açılır açılmaz ekrana bastırma işlemi gerçekleşmedi, bunun da sebebi fonksiyonun içinde fonksiyon tanımlanmış olması.

Eğer butonlara farklı özellikler yüklemek istiyorsanız. Böyle bir for döngüsü kurarak buton oluşturmak ve sonrasında butonlara tek tek farklı işlemler yapan fonksiyonlar tanımlamak uygun bir yöntem değil bence. Öyle bir durumda butonları tek tek tanımlamak zorunda kalabilirsiniz.

Kervan yolda düzülürmüş. Siz başlayın, takıldığınız yerde hepimiz yardımcı oluruz.