Uygulama 1 - Resim Görüntüleyici

Şimdiye kadar öğrendiklerimiz ile örnek bir uygulama yapma zamanı geldi. Çünkü uygulamadıkça öğrenmemiz eksik kalır. O yüzden bir örnek yapalım

Örneğimiz bir resim görüntüleyici. Bir klasör içinde bulunan resimleri listeler, sonra bunları ileri ve geri butonlarına bastıkça görüntüler. Planımız ise şöyle. Girişte bir yazı ve bir progressbar olacak. Resimler yüklenirken progressbar üzerinde yüklenme durumu gösterilecek. Tabi, resimler az olduğunda çok hızlı bir şekilde yüklenecek. Ancak örnekte de bulunsun diye bir progressbar eklemek istedim.

Resimlerimiz yüklendikten sonra, ekrandaki yazıyı ve progressbar’ı kaldırıp yerine ana ekranımızı koyacağız. Bunu da ayrı bir fonksiyon içinde yaptık. O zaman şimdi kodumuzu görelim, sonra da incelemeye başlayalım

# -*- coding: utf-8 -*-
# Resim Görüntüleyici
# Yazbel

from kivy.app import App
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.label import Label
from kivy.uix.button import Button
from kivy.uix.widget import Widget
from kivy.uix.image import Image
from kivy.clock import Clock
from kivy.uix.progressbar import ProgressBar
import os

class Program(App):

    def resimYukle(self,dosya_yolu):
        # Format listesi
        liste = ["png","gif","jpeg","jpg"]

        # Dosyaların listesini alma
        dosyaListesi = os.listdir(dosya_yolu)
        self.sayac = 0
        self.bar.max = len(dosyaListesi)
        self.bar.value = 0

        # Resim dosyalarını tespit etme
        for i in dosyaListesi:
            if(i.split(".")[-1] in liste):
                self.resimListesi.append(i)

            self.sayac += 1
            self.bar.value = self.sayac

        # Resimlerin yüklenmesi bittikten sonra, görüntüleme ekranını başlatmak üzere
        # self.basla fonksiyonuna git
        self.yukleniyor.text = "Resimler yüklendi"
        Clock.schedule_once(self.basla,1.5)

    def build(self):
        self.resimYolu = "resim/"
        self.resimListesi = list()
        self.resimSirasi = 0

        self.yukleniyor = Label(text = "Resimler yükleniyor...")
        self.bar = ProgressBar()

        self.govde = BoxLayout(orientation = "vertical")
        self.govde.add_widget(self.yukleniyor)
        self.govde.add_widget(self.bar)

        # Resimleri yüklemek üzere, self.resimYukle fonksiyonuna git
        Clock.schedule_once(lambda event = None:self.resimYukle(self.resimYolu),1)

        return self.govde

    def basla(self,event = None):
        # Ekrandaki tüm araçları kaldırıyoruz
        self.govde.clear_widgets()

        # Ve yeni araçlarımızı ekliyoruz
        self.bilgi = Label(text = "[color=#05f]Yazbel[/color] Resim Görüntüleyici",
                               markup = True,
                               size_hint_y = .1)
        self.resim = Image(source = self.resimYolu+self.resimListesi[0],
                           allow_stretch = True,
                           keep_ratio = True)


        # Geri ve ileri butonlarını taşıyan BoxLayout
        self.butonBar = BoxLayout(size_hint_y = .15)

        self.ileri = Button(text = "ileri",
                            size_hint_x = .2,
                            on_release = self.ileriYukle
                            )

        self.geri = Button(text = "geri",
                           size_hint_x = .2,
                           on_release = self.geriYukle)

        self.butonBar.add_widget(self.geri)
        self.butonBar.add_widget(Widget())
        self.butonBar.add_widget(self.ileri)

        self.govde.add_widget(self.bilgi)
        self.govde.add_widget(self.resim)
        self.govde.add_widget(self.butonBar)


    def ileriYukle(self,event = None):
        self.resimSirasi += 1

        # Eğer resim sırası listemizin boyutunu aşmamışsa
        if(self.resimSirasi < len(self.resimListesi)):
            try:
                self.resim.source = self.resimYolu+self.resimListesi[self.resimSirasi]
                self.bilgi.text = self.resimListesi[self.resimSirasi]
            except Exception as e:
                self.bilgi.text = "Yuklenemedi: {}".format(self.resimListesi[self.resimSirasi])

        # Eğer liste boyutunu aşmışsa, bunu sıfırlıyoruz
        else:
            try:
                self.resimSirasi = 0
                self.resim.source = self.resimYolu+self.resimListesi[self.resimSirasi]
                self.bilgi.text = self.resimListesi[self.resimSirasi]

            except Exception as e:
                self.bilgi.text = "Yuklenemedi: {}".format(self.resimListesi[self.resimSirasi])


    def geriYukle(self,event = None):
        self.resimSirasi -= 1

        # Eğer resim sırası listemizin boyutunun altına düşmemişse
        if(self.resimSirasi >= 0):
            try:
                self.resim.source = self.resimYolu+self.resimListesi[self.resimSirasi]
                self.bilgi.text = self.resimListesi[self.resimSirasi]
            except Exception as e:
                print(e)
                self.bilgi.text = "Yuklenemedi: {}".format(self.resimListesi[self.resimSirasi])

        # Eğer düşmüşse, yani negatif olduysa
        # sırayı listenin sonuna alıyoruz
        else:
            try:
                self.resimSirasi = len(self.resimListesi)-1
                self.resim.source = self.resimYolu+self.resimListesi[self.resimSirasi]
                self.bilgi.text = self.resimListesi[self.resimSirasi]
            except Exception as e:
                print(e)
                self.bilgi.text = "Yuklenemedi: {}".format(self.resimListesi[self.resimSirasi])

Program().run()

Öncelikle, programımız başlar başlamaz yazıyı ve progressbar’ı ekliyoruz sonra da resimlerin yüklenmesi için self.resimYukle fonksiyonuna gidiyoruz.

def resimYukle(self,dosya_yolu):
    # Format listesi
    liste = ["png","gif","jpeg","jpg"]

    # Dosyaların listesini alma
    dosyaListesi = os.listdir(dosya_yolu)
    self.sayac = 0
    self.bar.max = len(dosyaListesi)
    self.bar.value = 0

    # Resim dosyalarını tespit etme
    for i in dosyaListesi:
        if(i.split(".")[-1] in liste):
            self.resimListesi.append(i)

        self.sayac += 1
        self.bar.value = self.sayac

    # Resimlerin yüklenmesi bittikten sonra, görüntüleme ekranını başlatmak üzere
    # self.basla fonksiyonuna git
    self.yukleniyor.text = "Resimler yüklendi"
    Clock.schedule_once(self.basla,1)

Bu fonksiyonda ilk olarak, hangi resim formatlarını göstereceğimizi bir listede tuttuk. Farklı resim formatları da ekleyebilirsiniz. Biz şimdilik bu 4 formatı tercih ettik. Bu formatlar dışındaki resimleri dikkate almayacaktır.

Formatlarımızı tanımladıktan sonra, os.listdir() yardımıyla hangi klasördeki resimleri göstermek istiyorsak, o klasördeki dosyaları liste olarak elde ediyoruz. Bakın resimleri değil, dosyaları diyorum. Çünkü os.listdir() sadece verilen dizindeki dosyaların listesini verir. Bu listeden resim dosyalarını, bizim belirlediğimiz formatta olanları, ayırt etmek bizim işimiz.

Bu yüzden hemen aşağısında for döngüsü ile bu listenin elemanlarını tek tek kontrol ettik, ve uzantısı bizim belirttiğimiz uzantılardan biriyle eşleşiyorsa, self.resimListesi adlı listemize ekledik.

Tüm resimleri tespit ettikten sonra, 1 saniye sonra self.basla fonksiyonuna gidiyoruz. Bu fonksiyonda, ekrandaki tüm araçları self.govde.clear_widgets() ile temizledik ve yeni araçlarımızı ekledik.

def basla(self,event = None):
    # Ekrandaki tüm araçları kaldırıyoruz
    self.govde.clear_widgets()

    # Ve yeni araçlarımızı ekliyoruz
    self.bilgi = Label(text = "[color=#05f]Yazbel[/color] Resim Görüntüleyici",
                           markup = True,
                           size_hint_y = .1)
        self.resim = Image(source = self.resimYolu+os.sep+self.resimListesi[0],
                       allow_stretch = True,
                       keep_ratio = True)


    # Geri ve ileri butonlarını taşıyan BoxLayout
    self.butonBar = BoxLayout(size_hint_y = .15)

    self.ileri = Button(text = "ileri",
                        size_hint_x = .2,
                        on_release = self.ileriYukle
                        )

    self.geri = Button(text = "geri",
                       size_hint_x = .2,
                       on_release = self.geriYukle)

    self.butonBar.add_widget(self.geri)
    self.butonBar.add_widget(Widget())
    self.butonBar.add_widget(self.ileri)

            self.govde.add_widget(self.bilgi)
            self.govde.add_widget(self.resim)
            self.govde.add_widget(self.butonBar)

Bu fonksiyonda yabancı olduğumuz bir kod yok sanırım.Kullandığımız tüm pencere araçlarını daha önce gördük. Sadece butonBar içine eklediğimiz bir adet boş widget var. Onu da iki butonun arasını doldurmak için ekledik. Eklemeseydik de olurdu tabi.

Butonlarımızı ekledik ve ileri butonuna tıklandığı zaman, self.ileriYukle fonksiyonumuzun çalışmasını sağladık.

def ileriYukle(self,event = None):
    self.resimSirasi += 1

    # Eğer resim sırası listemizin boyutunu aşmamışsa
    if(self.resimSirasi < len(self.resimListesi)):
        try:
            self.resim.source = self.resimYolu+os.sep+self.resimListesi[self.resimSirasi]
            self.bilgi.text = self.resimListesi[self.resimSirasi]
        except Exception as e:
            self.bilgi.text = "Yuklenemedi: {}".format(self.resimListesi[self.resimSirasi])

    # Eğer liste boyutunu aşmışsa, bunu sıfırlıyoruz
    else:
        try:
            self.resimSirasi = 0
            self.resim.source = self.resimYolu+os.sep+self.resimListesi[self.resimSirasi]
            self.bilgi.text = self.resimListesi[self.resimSirasi]

        except Exception as e:
            self.bilgi.text = "Yuklenemedi: {}".format(self.resimListesi[self.resimSirasi])

İlk olarak resimSirasi değişkenini 1 artırıyoruz ve sonra da bu değerin listemizin boyutunu aşıp aşmadığını kontrol ediyoruz. Çünkü eğer boyutunu aşarsa, “liste boyutu aşıldı” hatası alabiliriz. Bu yüzden eğer boyutu aştıysa, değerini tekrardan 0 yapıyoruz

Geri butonumuz için de benzer şeyleri yapıyoruz

def geriYukle(self,event = None):
    self.resimSirasi -= 1

    # Eğer resim sırası listemizin boyutunun altına düşmemişse
    if(self.resimSirasi >= 0):
        try:
            self.resim.source = self.resimYolu+os.sep+self.resimListesi[self.resimSirasi]
            self.bilgi.text = self.resimListesi[self.resimSirasi]
        except Exception as e:
            print(e)
            self.bilgi.text = "Yuklenemedi: {}".format(self.resimListesi[self.resimSirasi])

    # Eğer düşmüşse, yani negatif olduysa
    # sırayı listenin sonuna alıyoruz
    else:
        try:
            self.resimSirasi = len(self.resimListesi)-1
            self.resim.source = self.resimYolu+os.sep+self.resimListesi[self.resimSirasi]
            self.bilgi.text = self.resimListesi[self.resimSirasi]
        except Exception as e:
            print(e)
            self.bilgi.text = "Yuklenemedi: {}".format(self.resimListesi[self.resimSirasi])

Burada farklı olarak, resimSirasi değerinin eksiye düşüp düşmediğini kontrol ettik. Eksiye düştüyse, tekrar listenin sonuna alıyoruz. Böylece bir döngü içinde resimlerin görüntülenmesini sağladık.

Örnekte bulunan os.sep, bulunduğunuz işletim sisteminde kullanılan dizin ayracını verir. Linux kullanıyorsanız, “/” Windows kullanıyorsanız “\” veya “" olarak belirlenir. Örnekte kullanmamızın sebebi, resim yolu ve resim adını birleştirdiğimizde araya dizin ayracı koymak. Eğer koymazsak, resmin bulunamadığına dair hata alırız.

>>> resimYolu+os.sep+resim
"resim/resim.jpg"

>>> resimYolu+resim
"resimresim.jpg"

Ben örnekte görüntülemek istediğim resimleri, program ile aynı klasörde bulunan “resim” adlı klasöre koydum. Eğer aynı klasörde bulunmayan başka bir klasörü listelemek isterseniz, tam dizini vermeniz gerekiyor. Yani “C:\resimler” gibi.

Programın görüntüsü şöyle

../../_images/uygulama-1.png

Gayet güzel çalışıyor. Kodu elimden geldiği kadar anlaşılır yazmaya çalıştım. Eğer anlamadığınız bir kısım olursa, veya hata olduğunu düşündüğünüz bir kısım varsa Forum üzerinden ulaşabilirsiniz.

Yorumlar

Önemli Not

Sorularınızı yorumlarda dile getirmek yerine Yazbel Forumunda sorarsanız çok daha hızlı cevap alabilirsiniz.
Belgelerdeki bir hata veya eksiği dile getirecekseniz lütfen yorumları kullanmak yerine Github'da bir konu (issue) açın.
Eğer yazdığınız yorum içinde kod kullanacaksanız kodlarınızı <pre><code> etiketleri içine alın. Örneğin:
        <pre><code class="python">
        print("Merhaba Dünya!")
        </code></pre>