4. Kivy Dili: kv (kv lang)

Kivy pencere düzenlerini oluşturmak için muhteşem bir dil sunmaktadır: kv Dili. Bu dili biraz HTML’ye biraz da css’ye benzetebilirsiniz. Bu bölümde kv dilini anlatmaya çalışacağız.

4.1. “Merhaba Dünya” yeniden

merhabaDunya.py programında ekrandaki “Merhaba Dünya” yazısını program kodu içerisinde bir etiket oluşturup, bu etiketin metinini değiştirerek yapmıştık. Bu etiketi daha sonra düzen olarak geri döndürmüştük (return Label()). Şimdi aynı pencereyi kv dilini kullanrak yapacağız. Önce program kodumuzu main.py‘deki gibi yazalım. Bu kodda hiçbir değişiklik yapmadan birçok pencere oluşturacağız.

Liste 4.1 main.py
1
2
3
4
5
6
from kivy.app import App

class girisFormu(App):
    pass

girisFormu().run()

Gördüğünüz gibi bu program hiçbirşey döndürmüyor. Sadece basit bir pencere oluşturuyor. Pencere içeriğini kv dili oluşturacağız. Şimdi dosyasını girisformu.kv programını kaydettiğiniz aynı dizinine (klasöre) kaydedin.

Liste 4.2 girisformu.kv
1
2
Label:
    text: "Merhaba Dünya"

Bu dosyanın adı, python programının dosya adı değil, uygulamanın adı ile aynı olacaktır. Eğer uygulamanızın adı kullaniciGirisFormu() ise kv dosyasının adı kullanicigirisformu.kv olacaktır. Dosya adında küçük harfleri kullanmanızı yeğlerim. Buradaki girisformu.kv oldukça basit bir yapıya sahip.Sadece iki satırdan ibaret ilk satır pencerede bir etiketin olacağı (Label), ikinci satırda ise bu etiketin üzerinde yazacak metni (text) belirtmektedir. Tıpkı Python’da olduğu gibi kv dilinde de girintiler (indendation) önemlidir. Birinci satır penceredeki grafik parçacığının ismini belirtmektedir. Grafik parçacığının isminden sonra iki nokta üst üste konulup sonraki satırda (sanki işlev tanımlar gibi), bu grafik parçacığının özelliklerine ait yapılanmayı biraz içerde başlatıyoruz.

main.py programını çalıştırdığınızda yine Şekil 3.1‘deki gibi bir pencere açılacaktır.

4.2. Kutu Pencere Düzeni (Box Layout)

Temel Bilgiler bölümündeki Pencere Düzenleri‘ni hatırlayın. Orada ızgara pencere düzenini oluşturmak için GridLayout() sınıfını kullanmıştık. kv dilinde de yine grafik parcacıklarının ismini kullanacağız. Kutu pencere düzeni BoxGridLayout() sınıfı ile oluşturulur. O halde kv dilinde BoxLayout ile kutu pencere düzenini oluşturabiliriz. Liste 4.3‘deki gibi değiştirin.

Liste 4.3 girisformu.kv
1
2
3
4
5
BoxLayout:
    Label:
        text: "Merhaba Dünya"
    Label:
        text: "Merhaba Kivy"

main.py programını tekrar çalıştırdığımızda Şekil 4.1‘deki gibi bir pencere açılacaktır.

_images/girisformu2Img.png

Şekil 4.1 Kutu Pencere Düzeni

Bu pencerede yan yana iki tane etiketin oluştuğunu görüyorsunuz. Kutu pencere düzeninin ön tanımlı yönelimi “yatay”dır (vertical). Eğer dikey olarak yönelndirmek istiyorsanız, pencere düzeninine orientation: ‘vertical’ satırını Liste 4.4‘deki gibi eklemelisiniz.

Liste 4.4 girisformu.kv
1
2
3
4
5
6
BoxLayout:
    orientation: 'vertical'
    Label:
        text: "Merhaba Dünya"
    Label:
        text: "Merhaba Kivy"

Şimdi Şekil 4.2‘deki gibi etiketlerimiz dikey olarak yerleşecektir.

_images/girisformu3Img.png

Şekil 4.2 Kutu Pencere Düzeni: Dikey Yönelimli

4.3. Izgara Pencere Düzeni (Grid Layout)

Izgara pencere düzenini dah önce görmüştük. Sütun ve satırlardan oluşuyordu. Şimdi Izgara Pencere düzenini kv dili oluşturacağız. girisformu.kv programını Liste 4.5‘deki gibi yazın. Metin kutularının TerxtInput ile oluşturulduğuna dikkat etmelisiniz.

Liste 4.5 girisformu.kv
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
GridLayout:
    cols: 2
    Label:
        text: "Kullanıcı Adı:"
    TextInput:
    Label:
        text: "Parola:"
    TextInput:
    Widget:
    Button:
        text: "Gir"

Burada iki sütunlu olması için cols: 2 satırını eklediğimize dikkat etmelisiniz. Yine aynı soruyu sormak istiyorum, 9. satırdaki Widget garfik parçacığını niçin koymuş olabiliriz? main.py programını çalıştırdığınızda Şekil 4.3‘deki gibi görünecektir.

_images/girisformu4Img.png

Şekil 4.3 Izgara Düzeni: Kullanıcı Giriş Formu

Aslında ızgara düzenini, kutu düzenlerini iç içe yazarakda yapabiliriz. Nihayetinde, ızgara düzeni dediğimiz, alt alta yerleştirilmiş (dikey yönelimli), yatay yönelimli kutulardan oluşmaktadır. Liste 4.6‘yi inceleyin.

Liste 4.6 girisformu.kv
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
BoxLayout:
    orientation: "vertical"
    BoxLayout:
        Label:
            text: "Kullanıcı Adı:"
        TextInput:
    BoxLayout:
        Label:
            text: "Parola:"
        TextInput:
    BoxLayout:
        Widget:
        Button:
            text: "Gir"

Burada gördüğünüz gibi, en üstte bir tane dikey yönelimli kutu pencere düzeni ve bunun altında üç tane yatay yönelimli kutu pencere düzeni yerleştirmiş olduk. İşimizi biraz uzattık, ancak konuyu anlamanız açısından bu örneği verdik. Liste 4.6 ve Liste 4.5 aynı görünütüyü oluşturur. Python programını (burada main.py) hiç değiştirmeden birçok kv dosyası ile kullandık ve serferinde farklı pencereler elde ettik. Liste 4.6‘deki 12. satırı (Widget: yazan satır) silersek, nasıl bir değişiklik oluşur? Bunu denemelisiniz.

4.4. Parçacık Boyutları (size_hint)

Grafik parçacıklarının görünür boyutlarını size_hint_x ve size_hint_y ayarlayabilirsiniz. Anlayacağınız üzere, size_hint_x yatay boyutun, size_hint_y ise dikey boyutun büyüklüğünü ayarlar. Ayarlamalar oran olarak yapılır. Örneğin yatay olarak yerleştirilmiş iki parcacıktan birisinin boyutu 1, diğerinin 4 ise, toplamı 5 yapacağından, ilk parcacık yatayın %20 sini, diğeri %80’nin kaplayacaktır. 3:2 olduğunda ne olabilir? İster yatay, ister dikey olsun birisine boyut bildirdiğinizde, diğerlerinede bildirmek durumundasınız. Aksi halde anlamsız olacaktır.

girisformu.kv dosyasını Liste 4.5‘deki gibi düzenleyelim.

Liste 4.7 girisformu.kv
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
BoxLayout:
    orientation: "vertical"

    BoxLayout:
        # 1. satırı oluşturan yatay kutu
        size_hint_y: 3
        Label:
            text: "Kullanıcı Adı:"
            size_hint_x: 1
        TextInput:
            size_hint_x: 3

    BoxLayout:
        # 2. satırı oluşturan yatay kutu
        size_hint_y: 2
        Label:
            text: "Parola:"
        TextInput:
            
    BoxLayout:
        # 3. satırı oluşturan yatay kutu
        size_hint_y: 1
        Button:
            text: "Gir"

Bunun üzerinde biraz konuşalım. Gördüğünüz gibi üç satır var. Her bir satır bir yatay kutu pencere düzeni tarafından oluşturulmakta, satırlar ise en üstteki dikey pencere kutusu ile alt alta getiriliyor. Üç adet satırın yükseklikleri sırası ile size_hint_y: 3, size_hint_y: 2 ve size_hint_y: 1 ile ayarlanmıştır (1., 2. ve 3. satırları oluşturan yatay kutular). Bunun anlamı dikey boyutun yarısı 1. yatay kutu tarafından kaplanacaktır. Geri kalan yarısının %66.6’sı 2. yatay kutu ve %33.3’ü ise 3. yatay kutu tarafından kaplanacaktır. Yatay büyüklük ise sadece 1. yatay kutu için ayarlanmıştır. %25’i etiket tarafından (Kullanıcı Adı etiketi), %75’i ise metin kutusu tarafından kullanılacaktır. Programımızı çalıştırdığımızda Şekil 4.3‘deki gibi görünecektir.

_images/girisformu5Img.png

Şekil 4.4 Boyutlandırılmış Giriş Formu

4.5. İkisi Bir Arada

Aslında bu kadar küçük programlar için kv içeriğini farklı bir dosyaya yazmaya gerek yok. Bunun yerine Python programı içerisine kv içeriğini de yazabiliriz. Liste 4.8‘de bunu görüyorsunuz.

Liste 4.8 main.py
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
# -*- coding: utf-8 -*-

from kivy.app import App
from kivy.lang import Builder

kv='''
BoxLayout:
    orientation: "vertical"
    BoxLayout:
        Label:
            text: "Kullanıcı Adı:"
        TextInput:
    BoxLayout:
        Label:
            text: "Parola:"
        TextInput:
            password: True
    BoxLayout:
        Widget:
        Button:
            text: "Gir"
'''

class girisFormu(App):

    def build(self):
        self.root=Builder.load_string(kv)
        return self.root


girisFormu().run()

Gördüğünüz gibi, kv içeriği bir Python programı içerisindeki bir cümleden alınıyor ve Builder nesnesinin load_string() özelliği ile yükleniyor. Şimdilik neden ana pencerenin self.root değişkenine aktarılıp build() tarafından döndürüldüğünden bahsetmeyeceğiz. Çeşitli pencere düzenleri, ve grafik parçacığı büyüklükleri ile deneyiniz. Buradaki bir diğer değişiklik, parolanın yazılacağı metin kutusunun gerçek bir parola alanı olduğudur. Bunu password: True özelliği ile yaptık. Artık bu alana yazılırken, yazılan karakterler görüntülenmez yerine yıldız (*) görüntülenir.

Bir metin kutusuna (TextInput), parola alanı yapacaksak, password özelliğinin değerini True yapmalısınız. Bunu kod ile yapmak istiyorsanız

parola = TextInput(password=True)

ya da, daha sonra yapmak için:

parola = TextInput()
parola.password=True

kv dili ile pencereleri oluşturmayı öğrendiğimize göre, şimdi biraz bu pencereleri işler hale getirmeye geldi. Sonraki bölümde garfik parçacıkları ile kullanıcı etkileşmesinin nasıl gerçekleştiğini göreceğiz.