Top Banner
Kivy Mobil Programlama Sürüm 0.2 Mustafa Ba ¸ ser Kas 28, 2017
126

Kivy Mobil Programlama - Read the Docs4 Kivy Dili: kv (kv lang) 15 ... Kivy Mobil Programlama, Sürüm 0.2 ... all users” seçili iken “Next” dügmesine tıkladı˘ gınızda

Jan 19, 2020

Download

Documents

dariahiddleston
Welcome message from author
This document is posted to help you gain knowledge. Please leave a comment to let me know what you think about it! Share it to your friends and learn new things together.
Transcript
Page 1: Kivy Mobil Programlama - Read the Docs4 Kivy Dili: kv (kv lang) 15 ... Kivy Mobil Programlama, Sürüm 0.2 ... all users” seçili iken “Next” dügmesine tıkladı˘ gınızda

Kivy Mobil ProgramlamaSürüm 0.2

Mustafa Baser

Kas 28, 2017

Page 2: Kivy Mobil Programlama - Read the Docs4 Kivy Dili: kv (kv lang) 15 ... Kivy Mobil Programlama, Sürüm 0.2 ... all users” seçili iken “Next” dügmesine tıkladı˘ gınızda
Page 3: Kivy Mobil Programlama - Read the Docs4 Kivy Dili: kv (kv lang) 15 ... Kivy Mobil Programlama, Sürüm 0.2 ... all users” seçili iken “Next” dügmesine tıkladı˘ gınızda

Içindekiler

1 Giris 31.1 Kivy Hakkında . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31.2 Belge Hakkında . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31.3 Ne Bilmeliyim? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 41.4 UYARI . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4

2 Kivy’nin Kurulumu 52.1 Windows’da Kurulum . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 52.2 Linux’da Kurulum . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6

3 Temel Bilgiler 73.1 Merhaba Dünya . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 73.2 Pencere Düzenleri . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8

4 Kivy Dili: kv (kv lang) 154.1 “Merhaba Dünya” yeniden . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 154.2 Kutu Pencere Düzeni (Box Layout) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 164.3 Izgara Pencere Düzeni (Grid Layout) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 174.4 Parçacık Boyutları (size_hint) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 184.5 Ikisi Bir Arada . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19

5 Andoid’de Çalıstırma: Kivy Launcher 215.1 Kivy Launcher Kurulumu . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 215.2 Kivy Launcher’a Uygulama Eklenmesi . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 215.3 Kivy Launcher’da Uygulamanın Baslatılması . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 23

6 Olaylar ve Popup 276.1 Isaret Dili (markup) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 296.2 Popup Pencere: (popup) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31

7 Metin Düzenleyici 357.1 Ana Pencere . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 357.2 Farklı Kaydet . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 367.3 Kaydet . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 417.4 Aç . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 427.5 Yeni . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 457.6 Çıkmadan Önce . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 46

i

Page 4: Kivy Mobil Programlama - Read the Docs4 Kivy Dili: kv (kv lang) 15 ... Kivy Mobil Programlama, Sürüm 0.2 ... all users” seçili iken “Next” dügmesine tıkladı˘ gınızda

8 Paketleme 498.1 Buildozer Kurulumu . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 498.2 Paket Derleme . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 508.3 Imzalama . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 518.4 Sanal Linux Makina . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 52

9 Atlıkarınca ve Resim Gösterici 599.1 Atlıkarınca (Carousel) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 599.2 Resim Gösterici . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 609.3 Zamanlayıcı ve Slayt Gösterisi . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 669.4 Kronometre Uygulaması . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 69

10 Liste Görünümü ve Eylem Çubugu 7110.1 Liste Görünümü . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7110.2 Açılır Kutu . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8510.3 Eylem Çubugu . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 92

11 Sekmeli Panel (TabbedPanel) ve Agaç Görünümü (TreeView) 10511.1 Kod ile Sekmeli Panel Olusturulması . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10511.2 kv Dili ile Sekmeli Panel Olusturulması . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10711.3 Agaç Görünümü (TreeView) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 108

12 Pencere Yöneticisi (ScreenManager) 11312.1 Kod ile Pencere Yöneticisi . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11312.2 Pencerelerin Kv Dili ile Hazırlanması . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 114

13 SQLite Tarayıcı (Son Bölüm) 117

14 Dizinler ve Tablolar 119

ii

Page 5: Kivy Mobil Programlama - Read the Docs4 Kivy Dili: kv (kv lang) 15 ... Kivy Mobil Programlama, Sürüm 0.2 ... all users” seçili iken “Next” dügmesine tıkladı˘ gınızda

Kivy Mobil Programlama, Sürüm 0.2

Içindekiler:

Içindekiler 1

Page 6: Kivy Mobil Programlama - Read the Docs4 Kivy Dili: kv (kv lang) 15 ... Kivy Mobil Programlama, Sürüm 0.2 ... all users” seçili iken “Next” dügmesine tıkladı˘ gınızda

Kivy Mobil Programlama, Sürüm 0.2

2 Içindekiler

Page 7: Kivy Mobil Programlama - Read the Docs4 Kivy Dili: kv (kv lang) 15 ... Kivy Mobil Programlama, Sürüm 0.2 ... all users” seçili iken “Next” dügmesine tıkladı˘ gınızda

BÖLÜM 1

Giris

Bu belge Kivy ile mobil programlamayı ögretmek amacı ile hazırlanmıstır.

1.1 Kivy Hakkında

Kivy mobil cihazlarda da çalısabilecek programların yazılabilecegi bir Python modülüdür. Diger bir deyisle MobilGUI Toolkit (Mobil Grafik Kullanıcı Arayüzü Aracı) diyebiliriz. Python ile Mobil Uygulama gelistirmek isteyenlerinçogunlugu Kivy’i tercih etmektedir. Kivy ile yazacagınız programlar hemen her platformda çalısabilir. Bu platformlarısöyle sıralaybiliriz;

• Masaüstü Bilgisayarlar: Linux, Mac OS X, Windows

• Talbletler: Android cihaziar, iPad, iPhone

Kivy dokunmatik ekranlar için optimize edilmis olmasına ragmen, gelistirilen uygulamalar masaüstü bilgisayarlardada rahatlıkla çalısabilmektedir. Bununla birlikte masaüstü bilgisayarlarda kullanılan diger GUI araçlarındaki birçoközelligi bulma sansınız yok.

Kivy aslında Pygame üzerine kurulmus bir yapıdır. Tüm widgetler (grafik bilesenleri) Pygame ile çizilmektedir. Kivyile yazdıgınız (aslında programı Python programa dili ile yazıyorsunuz) programlar, bir Linux makina (veya sanalmakinada çalısan bir Linux) ile kolaylıkla Android paketleri haline getirilebilmektedir. Getirilen paketler içerisindePython ve diger bilesenler eklendiginden, uygulama paketi kuruldugunda baska herhangi bir eklentiye gerek kalmadançalısmaktadır.

1.2 Belge Hakkında

Bu belge Mustafa Baser tarafından zaman buldukça hazırlanmaktadır ve sahibi © 2016, Mustafa Baser‘dir. Bu belgeGNU Özgür Belgeleme Lisansı ile dagıtılmaktadır.

3

Page 8: Kivy Mobil Programlama - Read the Docs4 Kivy Dili: kv (kv lang) 15 ... Kivy Mobil Programlama, Sürüm 0.2 ... all users” seçili iken “Next” dügmesine tıkladı˘ gınızda

Kivy Mobil Programlama, Sürüm 0.2

1.2.1 Sürüm ve son degisiklik

Sürüm: 0.2Son Degistirme Tarihi: Tue Nov 28 22:52:18 2017

1.2.2 Belgeye katkıda bulunanlar

• Mustafa Baser

Katkıda bulunmak için mbaser <at> mail.com adresine mail atabilirsiniz.

1.3 Ne Bilmeliyim?

Bu doküman sadece Kivy üzerinde yogunlasacaktır. Kivy ile program yazabilmek için Python bilmeniz gerekir. Pyt-hon’u çesitli web sitelerinden ya da bu dokümanın yazarı tarafından yazılmıs Dikeyeksen yayınlarındaki Python kita-bından ögrenebilirsiniz. Kitabın birinci kısmını ögrendiginiz varsayılmıstır.

Bunun dısında komut satırına (Windows için cmd) asina olmanız gerekmektedir. Böylelikle Paketleme bölümündeanlatacagımız sanal makina üzerinde paketleme isini yapabilirsiniz.

1.4 UYARI

Bu belgede anlatılan içerik ve yayınlanan programlar ve kurulmu anlatılan programlmarın/paketlerin neden olabilecegisorunlardan belgenin yazarı sorumlu tutulamaz.

4 Bölüm 1. Giris

Page 9: Kivy Mobil Programlama - Read the Docs4 Kivy Dili: kv (kv lang) 15 ... Kivy Mobil Programlama, Sürüm 0.2 ... all users” seçili iken “Next” dügmesine tıkladı˘ gınızda

BÖLÜM 2

Kivy’nin Kurulumu

Bu belgede tüm çalısmalar Linux üzerinde yapılmaktadır, ancak okuyucuların bir kısmının Windows üzerinde çalısmaihtimaline karsı Windows üzerinde kurulumda anlatılacaktır.

Bu belgenin hazırlanmaya basladıgı zamanda, Paketleme bölümünde anlatacagımız Buildozer Python 2.7 ile hazırlan-dıgı için Python 2.7 ile çalısılacaktır.

2.1 Windows’da Kurulum

Bu belgeyi okumaya baslamıs iseniz, muhtemelen bilgisayarınızda Python kuruludur. Eger kurulu degilse Python’unIndirme Sayfası‘na giderek isletim sisteminize uygun olan 2.7 sürümünün son paketini indiriniz. Bu belge hazırlanır-ken 2.7.10 sürümü var idi. Belgenin üzerinde çalısıldıgı Makinada 64 bitlik Windows 7 kurulu oldugundan su paketindirildi “Windows x86-64 MSI installer” (python-2.7.10.amd64.msi). Indirdiginiz msi dosyası üzerine çift tıklayın,eger Windows’unuzun yönetici parolasını biliyorsanız, en iyisi tüm kullanıcılar için kurmaktır. Bunun için “Install forall users” seçili iken “Next” dügmesine tıkladıgınızda kurulacak olan patikanın C:\Python27\ olmasına özen gös-terin. Birkaç tıklamadan sonra size yönetici parolası soarcaktır. Python 3.4 sürümü çalısabilir python.exe dosyasınınbulundugu C:\Python27\ patikasını çevre degiskenine eklemez. Bunun için önce bir komut satırı açın (Baslat’atıklayın “Programları ve dosyaları ara” kutucuguna cmd yazın ve klavyeden “Enter” tusuna basın. Bu size siyah siyahbir pencere açacaktır. Bu pencerede asagıdaki komutu isletin:

setx path "%path%;C:\Python27\"

Artık Kivy’nin kurulumuna geçebiliriz. Bunun için komut satırında iken (siyah pencerede) asagıdaki adımlarda belir-tilen komutları çalıstırın:

1. pip ve wheel‘in son sürümünü yükleyelim:

python -m pip install --upgrade pip wheel setuptools

2. Kivy için gerekli olan pakteleri kuralım (~100MB civarı dosya yüklenecektir biraz sabırlı olmalısınız):

python -m pip install docutils pygments pypiwin32 kivy.deps.sdl2 kivy.deps.→˓glew kivy.deps.gstreamer --extra-index-url https://kivy.org/downloads/→˓packages/simple/

5

Page 10: Kivy Mobil Programlama - Read the Docs4 Kivy Dili: kv (kv lang) 15 ... Kivy Mobil Programlama, Sürüm 0.2 ... all users” seçili iken “Next” dügmesine tıkladı˘ gınızda

Kivy Mobil Programlama, Sürüm 0.2

3. Ve son olarak Kivy’i kuralım:

python -m pip install kivy

Kurulum bitti, artık kivy’i python içerisinden çagırabilirsiniz. Düzgün kurulup kurulmadıgını Python komut satırındanasagıdaki kodları çalıstırarak deneyebilirsiniz. Kurulum düzgün ise pencere baslıgı “Bos Pencere” olan siyah ve bosbir pencere açılacaktır.

>>> from kivy.app import App>>> App(title="Bos Pencere").run()

2.2 Linux’da Kurulum

Degisik Linux dagıtımlarında kurulum birbirinden farklıdır. Burada sadece Debian Jessie’de (8.3) nasıl kurulacagınıanlatacagız. Tek yapmanız gereken:

# apt-get install python-kivy

kurulumun dogru gerçeklestigini yukarıda anlattıgım gibi ile anlayabilirsiniz.

6 Bölüm 2. Kivy’nin Kurulumu

Page 11: Kivy Mobil Programlama - Read the Docs4 Kivy Dili: kv (kv lang) 15 ... Kivy Mobil Programlama, Sürüm 0.2 ... all users” seçili iken “Next” dügmesine tıkladı˘ gınızda

BÖLÜM 3

Temel Bilgiler

Bu bölümde Kivy’e giris düzeyinde temel bilgiler verilecektir.

3.1 Merhaba Dünya

Hemen her programlma dilinde ilk yazılan program “Merhaba Dünya” cümlesinin yazılmasıdır. Bu belgede de bugelenegi bozmayacagız ve Kivy’i ögrenmeye bununla baslayacagız. IDLE’e kullanarak asagıdaki program kodunuyazın ve merhabaDunya.py olarak kaydedin.

Liste 3.1: merhabaDunya.py

1 # -*- coding: utf-8 -*-2

3 from kivy.app import App4 from kivy.uix.label import Label5

6 class ilkUygulama(App):7

8 def build(self):9 return Label(text='Merhaba Dünya!')

10

11 ilkUygulama().run()

Programı çalıstırdıgınızda Sekil 3.1‘deki gibi bir pencere açılacaktır.

Biraz bu program üzerinde konusalım. Buraya kadar geldiginize göre import satırlarını biliyor olmalısınız, bu ne-denle burayı geçiyorum. Bütün Kivy programları bir ana sınıf tarafından yönetilir. Bu ana sınıf Kivy’deki App sınıfınıiçerir. Bu programdaki ana sınıfımız ilkUygulama() dır. Ana sınıftaki build() islevi mutlaka bir pencere düzenidöndürür ve bu düzen program açıldıgında kullanıcnın ilk gördügü penceredir. Ana sınıf tarafından olusturulan pene-cereye Ana Pencere diyoruz. Buradaki program çok basit oldugundan bir pencere düzeni döndürmek yerine sadece biretiket (Label) döndürmüstür, ve bu etiket Ana Pencere olarak karsımıza çıkmaktadır. Uygulamanın çalıstırılması, anasınıfın run() özelligi ile yapılır. Buradaki ilkUygulama().run() satırı uygulamamızın çalısmasını saglar.

7

Page 12: Kivy Mobil Programlama - Read the Docs4 Kivy Dili: kv (kv lang) 15 ... Kivy Mobil Programlama, Sürüm 0.2 ... all users” seçili iken “Next” dügmesine tıkladı˘ gınızda

Kivy Mobil Programlama, Sürüm 0.2

Sekil 3.1: Merhaba Dünya

Eger pencere ismi verilmemisse, pencerinin baslıgında ana sınıfın ismi görünecektir. Pencere baslıgını degistirmekiçin, title özelligini kullanabiliriz. Sınıf tanımlanır tanımlanmaz hemen altında (def build(self): ile aynı hi-zada) asagıdaki satırı ekleyerek yapabilirsiniz:

title = 'Benim Kivy Programım'

Bir diger yöntem ise, build() islevi altında return etmeden hemen önce su satırı eklemektir:

self.title = 'Benim Kivy Programım'

Benzer sekilde pencere için kullanılacak olan simgeyi de icon özelligini kullanarak yapabilirsiniz. Son durumdabuild() islevini su sekilde yazabilirsiniz:

def build(self):self.title = 'Benim Kivy Programım'self.icon = 'simge.png'return Label(text='Merhaba Dünya!')

simge.png dosyası, ya merhaba_dunya.py dosyasının kaydedildigi yerde olmalı ya da tam patika yazılmalıdır.Örnegin resimler klasörüne koymus iseniz:

self.icon = 'resimler/simge.png'

seklinde yazılmalıdır.

3.2 Pencere Düzenleri

Bir pencereye birden fazla Grafik Parçacıgı (widget) koyacaksanız, bir pencere düzeni olusturmalısınız. Kivy prog-ramlarındaki pencere düzenleri iki sekilde olusturulabilir:

• Pencere düzenleri kodlarıya

• Kivy kv dili ile

8 Bölüm 3. Temel Bilgiler

Page 13: Kivy Mobil Programlama - Read the Docs4 Kivy Dili: kv (kv lang) 15 ... Kivy Mobil Programlama, Sürüm 0.2 ... all users” seçili iken “Next” dügmesine tıkladı˘ gınızda

Kivy Mobil Programlama, Sürüm 0.2

3.2.1 Izgara Pencere Düzeni

Bu belge kapsamında kv dili kullanılacaktır. Ancak bir fikir vermesi açısından kodlayarak nasıl yapıldıgını basit birörnek ile açıklamaya çalısalım. Söyle bir pencereye ihtiyacımız olsun:

Bunun için altı adet grafik parçacıgına (aslında pencere düzeni ile yedi) ihtiyacımız var. Iki tanesi etiket (Label) ikitanesi Metin Kutusu (TextInput) ve bir tanesi Dügme (index:Button). Bir tanede bos grafik parçacıgı (Widget). Buprogramı Liste 3.2 gibi yazabiliriz.

Liste 3.2: girisFormu.py

1 # -*- coding: utf-8 -*-2

3 from kivy.app import App4 from kivy.uix.widget import Widget5 from kivy.uix.gridlayout import GridLayout6 from kivy.uix.label import Label7 from kivy.uix.textinput import TextInput8 from kivy.uix.button import Button9

10 class girisFormu(App):11

12 def build(self):13

14 duzen = GridLayout(cols=2)15

16 duzen.add_widget(Label(text='Kullanıcı Adı:'))17 kullanici_adi = TextInput()18 duzen.add_widget(kullanici_adi)19

20 duzen.add_widget(Label(text='Parola:'))21 parola = TextInput()22 duzen.add_widget(parola)23

24 duzen.add_widget(Widget())25

26 gir_dugme=Button(text='Gir')27 duzen.add_widget(gir_dugme)28

29 self.title = "Giris Formu"30

31 return duzen32

33

34 girisFormu().run()

3.2. Pencere Düzenleri 9

Page 14: Kivy Mobil Programlama - Read the Docs4 Kivy Dili: kv (kv lang) 15 ... Kivy Mobil Programlama, Sürüm 0.2 ... all users” seçili iken “Next” dügmesine tıkladı˘ gınızda

Kivy Mobil Programlama, Sürüm 0.2

Programımız simdilik bir ise yaramamaktadır. Tek yaptıgı bir giris penceresi olusturmak ve bunu kullanıcıya göster-mektir. Dügmenin nasıl kullanılacagı, metin kutularındaki degerlerin nasıl alınacagı ileriki konularda anlatılacaktır.Burada GridLayout ile ızgara pencere düzeni olusturulmustur. Bu sınıfa verilen cols=2 parametresi ızgaranın ikisütundan olusacagını söylemktedir. Kaç satırdan olusuacagını belirtmiyoruz. Bir garfik parçacıgına (burada ızgarapencere düzeni) bir baska grafik parçacıgını add_widget() ile ekliyoruz. Buradaki ızgaramız iki sütunlu oldugun-dan ızgara düzenine eklenen her iki parçacık bir satırda bulunur ve daha sonra yeni satıra geçilir. Simdi size bir soru:Sizce 24. satırı duzen.add_widget(Widget()) neden yazmısızdır?

Programımız çalıstıgında Sekil 3.2 ‘deki gibi bir pencere açılacaktır.

Sekil 3.2: Giris Formu

3.2.2 Kutu Pencere Düzeni

Benzer bir pencereyi kutu pencere düzeni ile olusturalım. Kutu pencere düzeni BoxLayout parçacıgı ile olusturulur.Liste 3.3 programını inceleyin.

Liste 3.3: girisFormu.py

1 # -*- coding: utf-8 -*-2

3 from kivy.app import App4 from kivy.uix.widget import Widget5 from kivy.uix.boxlayout import BoxLayout6 from kivy.uix.label import Label7 from kivy.uix.textinput import TextInput8 from kivy.uix.button import Button9

10 class girisFormu(App):11

12 def build(self):13

14 duzen = BoxLayout(orientation='vertical')15

16 duzen.add_widget(Label(text='Kullanıcı Adı:'))17 kullanici_adi = TextInput()18 duzen.add_widget(kullanici_adi)19

20 duzen.add_widget(Label(text='Parola:'))21 parola = TextInput()22 duzen.add_widget(parola)23

10 Bölüm 3. Temel Bilgiler

Page 15: Kivy Mobil Programlama - Read the Docs4 Kivy Dili: kv (kv lang) 15 ... Kivy Mobil Programlama, Sürüm 0.2 ... all users” seçili iken “Next” dügmesine tıkladı˘ gınızda

Kivy Mobil Programlama, Sürüm 0.2

24 duzen.add_widget(Widget())25

26 gir_dugme=Button(text='Gir')27 duzen.add_widget(gir_dugme)28

29 self.title = "Giris Formu"30

31 return duzen32

33

34 girisFormu().run()

Programımız çalıstıgında Sekil 3.3 ‘deki gibi bir pencere açılacaktır.

Sekil 3.3: Giris Formu (Dikey Yönelimli)

Bu pencere bizim istedigimiz degil. Kutu pencere düzeninin ön tanımlı yönelimi yataydır. Yani eklenen parça-cıklar yan yana görünür. Dikey olması için kutu pencere düzenini olusturan BoxLayout() grafik parçacıgınaorientation='vertical' paramteresini verdik. Dikey yönelimli bir kutu pencere düzeninde tüm parçacıklaralt alta eklenir. Oysaki biz, ilk etiket ile ilk metin kutusunu yan yana, sonraki ikilileri de yine yan yana istiyoruz. Ohalde, ana düzeni olusturan kutu pencere düzeninin ilk satırına bir baska kutu pencere düzeni yerlestirmeliyiz. Ikincikutu pencere düzeninine ekledigimiz parçacıklar zaten yan yana görünecektir. Anlatmak istedigimi asagıdaki sekildeçizdim:

Yukarıdaki çizimde gördügünüz pencere düzenini olusturacak program Liste 3.4‘dadır.

Liste 3.4: girisFormu.py

1 # -*- coding: utf-8 -*-2

3 from kivy.app import App4 from kivy.uix.widget import Widget5 from kivy.uix.boxlayout import BoxLayout6 from kivy.uix.label import Label7 from kivy.uix.textinput import TextInput8 from kivy.uix.button import Button9

3.2. Pencere Düzenleri 11

Page 16: Kivy Mobil Programlama - Read the Docs4 Kivy Dili: kv (kv lang) 15 ... Kivy Mobil Programlama, Sürüm 0.2 ... all users” seçili iken “Next” dügmesine tıkladı˘ gınızda

Kivy Mobil Programlama, Sürüm 0.2

10 class girisFormu(App):11

12 def build(self):13

14 duzen = BoxLayout(orientation='vertical')15

16 duzen_satir_1 = BoxLayout()17 duzen_satir_1.add_widget(Label(text='Kullanıcı Adı:'))18 kullanici_adi = TextInput()19 duzen_satir_1.add_widget(kullanici_adi)20 duzen.add_widget(duzen_satir_1)21

22 duzen_satir_2 = BoxLayout()23 duzen_satir_2.add_widget(Label(text='Parola:'))24 parola = TextInput()25 duzen_satir_2.add_widget(parola)26 duzen.add_widget(duzen_satir_2)27

28 duzen_satir_3 = BoxLayout()29 duzen_satir_3.add_widget(Widget())30 gir_dugme=Button(text='Gir')31 duzen_satir_3.add_widget(gir_dugme)32

33 duzen.add_widget(duzen_satir_3)34

35 self.title = "Giris Formu"36

37 return duzen38

39

40 girisFormu().run()

Liste 3.4‘deki programı çalıstırdıgımızda bize Sekil 3.2 ‘deki pencerenin aynısını verecektir.

12 Bölüm 3. Temel Bilgiler

Page 17: Kivy Mobil Programlama - Read the Docs4 Kivy Dili: kv (kv lang) 15 ... Kivy Mobil Programlama, Sürüm 0.2 ... all users” seçili iken “Next” dügmesine tıkladı˘ gınızda

Kivy Mobil Programlama, Sürüm 0.2

3.2.3 Diger Pencere Düzenleri

Kivy yukarıda anlattıgımız, pencere düzenlerinden daha fazlasını sunar. Tüm pencere düzenlerini söyle özatleyebiliriz.

AnchorLayout: Grafik parçacıkları ‘top’ (üst), ‘bottom’ (alt), ‘left’ (sol), ‘right’ (sag) veya ‘center’ (orta) konumayerlestirielbilirler.

BoxLayout: Grafik parçacıkları ‘vertical’ (dikey) veya ‘horizontal’ (yatay) yönelimli olarak yerlestirilebilirler.

FloatLayout: Grafik parçacıkları istenilen herhangi bir konuma yerlestirilebilirler.

RelativeLayout: Çocuk grafik parçacıkları düzene göreceli olarak yerlestirilebilirler.

GridLayout: Grafik parçacıkları ızgara seklinde yerlestirilebilirler.

PageLayout: Çoklu sayfa düzeni olusturmak için kullanılabilir.

ScatterLayout: Grafik parçacıkları RelativeLayout’da oldugu gibi yerlestirilebilir ancak bunlar dönrürülebilir ve öl-çeklenebilir.

StackLayout: Grafik parçacıkları üst-alt ve sag-sol’a kaydırılacak sekilde yerlestirilebilir.

Ihtiyaç oldukça bu pencere düzenlerini kullanacagız ve oralarda daha ayrıntılı açıklayacagız.

Pencere düzenlerinin kod yazarak olusturulması, mekanik bir islemi tekrarlamaktır. Kivy’de bizi bu dertten kurtarackbir diger yöntem vardır: kv lang (veya kv dili). Bunu Kivy Dili: kv (kv lang) bölümünde anlatacagız.

3.2. Pencere Düzenleri 13

Page 18: Kivy Mobil Programlama - Read the Docs4 Kivy Dili: kv (kv lang) 15 ... Kivy Mobil Programlama, Sürüm 0.2 ... all users” seçili iken “Next” dügmesine tıkladı˘ gınızda

Kivy Mobil Programlama, Sürüm 0.2

14 Bölüm 3. Temel Bilgiler

Page 19: Kivy Mobil Programlama - Read the Docs4 Kivy Dili: kv (kv lang) 15 ... Kivy Mobil Programlama, Sürüm 0.2 ... all users” seçili iken “Next” dügmesine tıkladı˘ gınızda

BÖLÜM 4

Kivy Dili: kv (kv lang)

Kivy pencere düzenlerini olusturmak için muhtesem bir dil sunmaktadır: kv Dili. Bu dili biraz HTML’ye biraz dacss’ye benzetebilirsiniz. Bu bölümde kv dilini anlatmaya çalısacagız.

4.1 “Merhaba Dünya” yeniden

merhabaDunya.py programında ekrandaki “Merhaba Dünya” yazısını program kodu içerisinde bir etiket olusturup, buetiketin metinini degistirerek yapmıstık. Bu etiketi daha sonra düzen olarak geri döndürmüstük (return Label()).Simdi aynı pencereyi kv dilini kullanrak yapacagız. Önce program kodumuzu main.py‘deki gibi yazalım. Bu koddahiçbir degisiklik yapmadan birçok pencere olusturacagız.

Liste 4.1: main.py

1 from kivy.app import App2

3 class girisFormu(App):4 pass5

6 girisFormu().run()

Gördügünüz gibi bu program hiçbirsey döndürmüyor. Sadece basit bir pencere olusturuyor. Pencere içerigini kv diliolusturacagız. Simdi dosyasını girisformu.kv programını kaydettiginiz aynı dizinine (klasöre) kaydedin.

Liste 4.2: girisformu.kv

1 Label:2 text: "Merhaba Dünya"

Bu dosyanın adı, python programının dosya adı degil, uygulamanın adı ile aynı olacaktır. Eger uygulamanızın adıkullaniciGirisFormu() ise kv dosyasının adı kullanicigirisformu.kv olacaktır. Dosya adında küçükharfleri kullanmanızı yeglerim. Buradaki girisformu.kv oldukça basit bir yapıya sahip.Sadece iki satırdan ibaret ilksatır pencerede bir etiketin olacagı (Label), ikinci satırda ise bu etiketin üzerinde yazacak metni (text) belirtmektedir.

15

Page 20: Kivy Mobil Programlama - Read the Docs4 Kivy Dili: kv (kv lang) 15 ... Kivy Mobil Programlama, Sürüm 0.2 ... all users” seçili iken “Next” dügmesine tıkladı˘ gınızda

Kivy Mobil Programlama, Sürüm 0.2

Tıpkı Python’da oldugu gibi kv dilinde de girintiler (indendation) önemlidir. Birinci satır penceredeki grafik parçacı-gının ismini belirtmektedir. Grafik parçacıgının isminden sonra iki nokta üst üste konulup sonraki satırda (sanki islevtanımlar gibi), bu grafik parçacıgının özelliklerine ait yapılanmayı biraz içerde baslatıyoruz.

main.py programını çalıstırdıgınızda yine Sekil 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 olusturmak içinGridLayout() sınıfını kullanmıstık. kv dilinde de yine grafik parcacıklarının ismini kullanacagız. Kutu penceredüzeni BoxGridLayout() sınıfı ile olusturulur. O halde kv dilinde BoxLayout ile kutu pencere düzenini olustu-rabiliriz. Liste 4.3‘deki gibi degistirin.

Liste 4.3: girisformu.kv

1 BoxLayout:2 Label:3 text: "Merhaba Dünya"4 Label:5 text: "Merhaba Kivy"

main.py programını tekrar çalıstırdıgımızda Sekil 4.1‘deki gibi bir pencere açılacaktır.

Sekil 4.1: Kutu Pencere Düzeni

Bu pencerede yan yana iki tane etiketin olustugunu görüyorsunuz. Kutu pencere düzeninin ön tanımlı yönelimi “ya-tay”dır (vertical). Eger dikey olarak yönelndirmek istiyorsanız, pencere düzeninine orientation: ‘vertical’ satırını Liste4.4‘deki gibi eklemelisiniz.

Liste 4.4: girisformu.kv

1 BoxLayout:2 orientation: 'vertical'3 Label:4 text: "Merhaba Dünya"5 Label:6 text: "Merhaba Kivy"

Simdi Sekil 4.2‘deki gibi etiketlerimiz dikey olarak yerlesecektir.

16 Bölüm 4. Kivy Dili: kv (kv lang)

Page 21: Kivy Mobil Programlama - Read the Docs4 Kivy Dili: kv (kv lang) 15 ... Kivy Mobil Programlama, Sürüm 0.2 ... all users” seçili iken “Next” dügmesine tıkladı˘ gınızda

Kivy Mobil Programlama, Sürüm 0.2

Sekil 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üstük. Sütun ve satırlardan olusuyordu. Simdi Izgara Pencere düzenini kv diliolusturacagız. girisformu.kv programını Liste 4.5‘deki gibi yazın. Metin kutularının TerxtInput ile olustu-rulduguna dikkat etmelisiniz.

Liste 4.5: girisformu.kv

1 GridLayout:2 cols: 23 Label:4 text: "Kullanıcı Adı:"5 TextInput:6 Label:7 text: "Parola:"8 TextInput:9 Widget:

10 Button:11 text: "Gir"

Burada iki sütunlu olması için cols: 2 satırını ekledigimize dikkat etmelisiniz. Yine aynı soruyu sormak istiyorum, 9.satırdaki Widget garfik parçacıgını niçin koymus olabiliriz? main.py programını çalıstırdıgınızda Sekil 4.3‘deki gibigörünecektir.

Sekil 4.3: Izgara Düzeni: Kullanıcı Giris Formu

Aslında ızgara düzenini, kutu düzenlerini iç içe yazarakda yapabiliriz. Nihayetinde, ızgara düzeni dedigimiz, alt altayerlestirilmis (dikey yönelimli), yatay yönelimli kutulardan olusmaktadır. Liste 4.6‘yi inceleyin.

4.3. Izgara Pencere Düzeni (Grid Layout) 17

Page 22: Kivy Mobil Programlama - Read the Docs4 Kivy Dili: kv (kv lang) 15 ... Kivy Mobil Programlama, Sürüm 0.2 ... all users” seçili iken “Next” dügmesine tıkladı˘ gınızda

Kivy Mobil Programlama, Sürüm 0.2

Liste 4.6: girisformu.kv

1 BoxLayout:2 orientation: "vertical"3 BoxLayout:4 Label:5 text: "Kullanıcı Adı:"6 TextInput:7 BoxLayout:8 Label:9 text: "Parola:"

10 TextInput:11 BoxLayout:12 Widget:13 Button:14 text: "Gir"

Burada gördügünüz gibi, en üstte bir tane dikey yönelimli kutu pencere düzeni ve bunun altında üç tane yatay yönelimlikutu pencere düzeni yerlestirmis olduk. Isimizi biraz uzattık, ancak konuyu anlamanız açısından bu örnegi verdik.Liste 4.6 ve Liste 4.5 aynı görünütüyü olusturur. Python programını (burada main.py) hiç degistirmeden birçok kvdosyası ile kullandık ve serferinde farklı pencereler elde ettik. Liste 4.6‘deki 12. satırı (Widget: yazan satır) silersek,nasıl bir degisiklik olusur? 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. Anlayacagınızüzere, size_hint_x yatay boyutun, size_hint_y ise dikey boyutun büyüklügünü ayarlar. Ayarlamalar oranolarak yapılır. Örnegin yatay olarak yerlestirilmis iki parcacıktan birisinin boyutu 1, digerinin 4 ise, toplamı 5 yapaca-gından, ilk parcacık yatayın %20 sini, digeri %80’nin kaplayacaktır. 3:2 oldugunda ne olabilir? Ister yatay, ister dikeyolsun birisine boyut bildirdiginizde, digerlerinede 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 BoxLayout:2 orientation: "vertical"3

4 BoxLayout:5 # 1. satırı olusturan yatay kutu6 size_hint_y: 37 Label:8 text: "Kullanıcı Adı:"9 size_hint_x: 1

10 TextInput:11 size_hint_x: 312

13 BoxLayout:14 # 2. satırı olusturan yatay kutu15 size_hint_y: 216 Label:17 text: "Parola:"18 TextInput:19

20 BoxLayout:

18 Bölüm 4. Kivy Dili: kv (kv lang)

Page 23: Kivy Mobil Programlama - Read the Docs4 Kivy Dili: kv (kv lang) 15 ... Kivy Mobil Programlama, Sürüm 0.2 ... all users” seçili iken “Next” dügmesine tıkladı˘ gınızda

Kivy Mobil Programlama, Sürüm 0.2

21 # 3. satırı olusturan yatay kutu22 size_hint_y: 123 Button:24 text: "Gir"

Bunun üzerinde biraz konusalım. Gördügünüz gibi üç satır var. Her bir satır bir yatay kutu pencere düzeni tarafındanolusturulmakta, 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ıstır (1., 2. ve 3. satırları olusturanyatay 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çinayarlanmıstır. %25’i etiket tarafından (Kullanıcı Adı etiketi), %75’i ise metin kutusu tarafından kullanılacaktır.Programımızı çalıstırdıgımızda Sekil 4.3‘deki gibi görünecektir.

Sekil 4.4: Boyutlandırılmıs Giris Formu

4.5 Ikisi Bir Arada

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

Liste 4.8: main.py

1 # -*- coding: utf-8 -*-2

3 from kivy.app import App4 from kivy.lang import Builder5

6 kv='''7 BoxLayout:8 orientation: "vertical"9 BoxLayout:

10 Label:

4.5. Ikisi Bir Arada 19

Page 24: Kivy Mobil Programlama - Read the Docs4 Kivy Dili: kv (kv lang) 15 ... Kivy Mobil Programlama, Sürüm 0.2 ... all users” seçili iken “Next” dügmesine tıkladı˘ gınızda

Kivy Mobil Programlama, Sürüm 0.2

11 text: "Kullanıcı Adı:"12 TextInput:13 BoxLayout:14 Label:15 text: "Parola:"16 TextInput:17 password: True18 BoxLayout:19 Widget:20 Button:21 text: "Gir"22 '''23

24 class girisFormu(App):25

26 def build(self):27 self.root=Builder.load_string(kv)28 return self.root29

30

31 girisFormu().run()

Gördügünüz gibi, kv içerigi bir Python programı içerisindeki bir cümleden alınıyor ve Builder nesnesininload_string() özelligi ile yükleniyor. Simdilik neden ana pencerenin self.root degiskenine aktarılıpbuild() tarafından döndürüldügünden bahsetmeyecegiz. Çesitli pencere düzenleri, ve grafik parçacıgı büyüklükleriile deneyiniz. Buradaki bir diger degisiklik, parolanın yazılacagı metin kutusunun gerçek bir parola alanı oldugudur.Bunu password: True özelligi ile yaptık. Artık bu alana yazılırken, yazılan karakterler görüntülenmez yerineyıldız (*) görüntülenir.

Bir metin kutusuna (TextInput), parola alanı yapacaksak, password özelliginin degerini True yapmalısınız. Bunu kodile yapmak istiyorsanız

parola = TextInput(password=True)

ya da, daha sonra yapmak için:

parola = TextInput()parola.password=True

kv dili ile pencereleri olusturmayı ögrendigimize göre, simdi biraz bu pencereleri isler hale getirmeye geldi. Sonrakibölümde garfik parçacıkları ile kullanıcı etkilesmesinin nasıl gerçeklestigini görecegiz.

20 Bölüm 4. Kivy Dili: kv (kv lang)

Page 25: Kivy Mobil Programlama - Read the Docs4 Kivy Dili: kv (kv lang) 15 ... Kivy Mobil Programlama, Sürüm 0.2 ... all users” seçili iken “Next” dügmesine tıkladı˘ gınızda

BÖLÜM 5

Andoid’de Çalıstırma: Kivy Launcher

Kivy ile uygulamalar çogunlukla mobil cihazlarda çalıstırmak için gelistirilir. Peki Windows yada Linux üzerindegelisrtirdigimiz programları Android üzerinde nasıl çalıstıracagız? Bunun bilinen yolu apk paketi olustrmaktır. Yazdı-gınız programları apk paketi haline getirmeyi Bölüm Paketleme de anlatacagız.

Paketleme bölümünde anlatacagımız apk paketi yapmak olduçka zahmetli ve uzun bir islemdir. Paketleme isini endogrusu programınız belirli bir olgunluga eristikten sonra yapmaktır. Her yaptıgınız degisiklikte programı derleyippaket haline getirmek ve bunu android cihaza kurup çalıstırmak, Python’un genel mantıgına aykırıdır. Yorulmalamalıbir dil ile yazdıgınız programları derleyip çalıstırmak, yorumlamalı dillerin en büyük avantajını geri plana itmek sayılır.Bu bölümde programınızı derlemenden, dogrudan kaynak kodu kullanarak çalıstırmanın yolunu anlatacagız.

5.1 Kivy Launcher Kurulumu

Python/Kivy ile yazılmıs programların derlenmeden dogrudan Android üzerinde çalısmasını saglayacak bir yorum-layıcıya ihtiyacımız olacak. Tıpkı Python yorumlayıcısı gibi. Android üzerinde kullanabileceginiz QPython isinizigörmeyecektir, çünkü QPython SL4A mekanızması ile çalısır. Kivy ve diger eklentileri kurmanız ve içermeniz müm-kün degildir. Kivy Launcher bu amaçla hazırlanmıs bir Python/Kivy yorumalyıcısıdır. Üstelik birçok Python paketinide içermektedir. Örnegin Pyjnius bile içerilmektedir.

Kivy Launcher‘ı kurmak için Google Play’i açın ve arama kutusuna “Kivy Launcher”. Bu bölümün yazıldıgı sıradaçıkan sonuç Sekil 5.1 ‘de görülmektedir.

“Yükle” dügmesine tıklayın ve kurulumu tamamlayın.

5.2 Kivy Launcher’a Uygulama Eklenmesi

Kivy Launcher birden fazla uygulamayı baslatablir. Bir programı çalıstırmak için SD karınızda kivy adlı bir kla-sör olusturmanız, uygulamanızı bu klasörün içerisinde bir klasöre kaydetmeniz gerekmektedir. Bu klasöre uygulamaklasörü diyecegiz. Uygulama klasöründe android.txt isimli dosyayı su sekilde olusturmalısınız:

21

Page 26: Kivy Mobil Programlama - Read the Docs4 Kivy Dili: kv (kv lang) 15 ... Kivy Mobil Programlama, Sürüm 0.2 ... all users” seçili iken “Next” dügmesine tıkladı˘ gınızda

Kivy Mobil Programlama, Sürüm 0.2

Sekil 5.1: Kivy Launcher Kurulumu

22 Bölüm 5. Andoid’de Çalıstırma: Kivy Launcher

Page 27: Kivy Mobil Programlama - Read the Docs4 Kivy Dili: kv (kv lang) 15 ... Kivy Mobil Programlama, Sürüm 0.2 ... all users” seçili iken “Next” dügmesine tıkladı˘ gınızda

Kivy Mobil Programlama, Sürüm 0.2

title=Uygulama Basligiauthor=Yazar Adi Soaydiorientation=portrait

orientation parametresi portrait (dikey) yada landscape (yatay) degerini alabilir.

Simdi Olaylar ve Popup Bölümünde yazdıgımız programı (Liste 6.9) ve ilgili kv dosyasını (Liste 6.8 kullana-rak) olayuyg.kv Kivy Launcher‘da çalıstıralım. Öncelikle SD karınızda olusturdugunuz kivy isimli klasördeolayApp isimli bir klasör olusturun. Liste 6.9 programını main.py olarak ve ile Liste 6.8 dosyasını olayuyg.kvolarak bu klasöre kopyalayın. Bu klasörde android.txt isimli dosyayı ben su sekilde olusturdum:

title=Olaylar ve PopUpauthor=Mustafa Baserorientation=portrait

Yaptıgımız islem Windows’da Sekil 5.2‘deki gibi görünecektir.

Sekil 5.2: Kivy Launcher’a Uygulama Eklenmesi

Kivy Launcher uygualama kalsöründeki main.py programını çalıstıracaktır. Bu nedenle simdiye kadar tüm program-larımızı main.py olarak kaydettik. Benzer sekilde apk paketi yapacagınız uygualamanın ana programı da main.pyolacaktır.

5.3 Kivy Launcher’da Uygulamanın Baslatılması

Android cihazınızda Kivy Launcher uygulamasını baslattıgınızda:

görünecektir. Uygulamıyı seçip baslatabilirsinz:

5.3. Kivy Launcher’da Uygulamanın Baslatılması 23

Page 28: Kivy Mobil Programlama - Read the Docs4 Kivy Dili: kv (kv lang) 15 ... Kivy Mobil Programlama, Sürüm 0.2 ... all users” seçili iken “Next” dügmesine tıkladı˘ gınızda

Kivy Mobil Programlama, Sürüm 0.2

Sekil 5.3: Kivy Launcher’da Uygulamalar

24 Bölüm 5. Andoid’de Çalıstırma: Kivy Launcher

Page 29: Kivy Mobil Programlama - Read the Docs4 Kivy Dili: kv (kv lang) 15 ... Kivy Mobil Programlama, Sürüm 0.2 ... all users” seçili iken “Next” dügmesine tıkladı˘ gınızda

Kivy Mobil Programlama, Sürüm 0.2

Sekil 5.4: Kivy Launcher’da Uygulamanın Çalısması

5.3. Kivy Launcher’da Uygulamanın Baslatılması 25

Page 30: Kivy Mobil Programlama - Read the Docs4 Kivy Dili: kv (kv lang) 15 ... Kivy Mobil Programlama, Sürüm 0.2 ... all users” seçili iken “Next” dügmesine tıkladı˘ gınızda

Kivy Mobil Programlama, Sürüm 0.2

Eger koduzunun çalıstırılamsı sırasındaki hataları görmek istiyordanız, CatLog isimli uygulamaya root yetkisi vererekgörebilirsiniz. Benim terchim Linux’da adb logcat komutunu kullanmaktır.

26 Bölüm 5. Andoid’de Çalıstırma: Kivy Launcher

Page 31: Kivy Mobil Programlama - Read the Docs4 Kivy Dili: kv (kv lang) 15 ... Kivy Mobil Programlama, Sürüm 0.2 ... all users” seçili iken “Next” dügmesine tıkladı˘ gınızda

BÖLÜM 6

Olaylar ve Popup

Türkçe’de “Ortaya çıkan, olusan durum” olarak tanımladıgımız olay (event), Kivy için de geçerlidir. Örnegin “düg-meye bastırmak”, “bastırılmayı bırakmak”, “seçim yapmak”, “bir tusa basmak” gibi birçok durum birer Kivy olayıdır.Bu olaylar gerçeklestiginde, programımızın bir tepki vermesi gerekir. Bir olay gerçeklestiginde verilecek tepki bir is-lev (fonksiyon) tarafından gerçeklestirilebilir. Olay gerçeklestiginde ilgili fonksiyonun çagrılabilmesi için, fonksiyonuolaya baglamak gerekmektedir.

Önce bir dügmeye bastırıldıgında üzeirndeki metnin degismesini saglayacak bir program yazmaya çalısalım. Bu prog-ramı öncelikle Python kodu yazarak ögrenecegiz, daha sonra kvlang ile nasıl gerçeklestirilebilecegine bakacagız.Programımız Liste 6.1‘de görülmektedir.

Liste 6.1: main.py

1 # -*- coding: utf-8 -*-2

3 from kivy.app import App4 from kivy.uix.boxlayout import BoxLayout5 from kivy.uix.button import Button6

7 class olayUyg(App):8

9 def metni_degistir(self, nesne):10 self.dugme.text='Tıkladın ve degistim.'11

12 def build(self):13 duzen=BoxLayout()14 self.dugme=Button(text='Degistir')15 self.dugme.bind(on_press=self.metni_degistir)16 duzen.add_widget(self.dugme)17 return duzen18

19 olayUyg().run()

Liste 6.1‘deki programı çalıstırdıgımızda tüm ekranı kaplayan bir dügme görünecektir. Dügmenin üzerinde “Degistir”metni görünmektedir. Bu dügmeyi self‘in bir özelligi yapmamaızın nedeni, sınıf içerisindeki tüm islevlerden erise-bilmektir. Bu dügmeye bastırıldıgında çagrılacak olan islevi, dügmeinin bind() özelligi ile baglıyoruz. Bir olayı bir

27

Page 32: Kivy Mobil Programlama - Read the Docs4 Kivy Dili: kv (kv lang) 15 ... Kivy Mobil Programlama, Sürüm 0.2 ... all users” seçili iken “Next” dügmesine tıkladı˘ gınızda

Kivy Mobil Programlama, Sürüm 0.2

nesneye baglamak için bind() özelligini kullanırız. Bu isleve, hangi olayı baglamak istiyorsak, onu parametre ve buparametreye de çagrılacak olan islevi yazıyoruz. 15. satırda bind() islevine on_press parametrisini (bu dügmeye bas-tırılma olayını ifade eder) ve deger olarak ta self.metni_degistir islevini atadık. Böylelikle dügmeye bastırıl-dıgında self.metni_degistir islevi çagrılacaktır. Çagrılan isleve nesnenin kendisi (burada self.dugme‘dir)argüman olarak gönderilir. Aslında dugme‘yi self‘in özelligi yapmadan, gelen nesne üzerinden de metni degistire-bilirdik:

nesne.text='Tıkladın ve degistim.'

aynı görevi görürdü. Simdi aynı programı kv lang ile yazalım. Programımızı Liste 6.2‘da görüyorsunuz.

Liste 6.2: main.py

1 # -*- coding: utf-8 -*-2

3 from kivy.app import App4

5 class olayUyg(App):6

7 def metni_degistir(self):8 self.root.ids.dugme.text='Tıkladın ve degistim.'9

10 olayUyg().run()

Ilgili kv dosyasını Liste 6.3‘da görüyorsunuz.

Liste 6.3: olayuyg.kv

1 BoxLayout:2 Button:3 id: dugme4 text: 'Degistir'5 on_press: app.metni_degistir()6

7

Simdi biraz program ve kv dosyası üzerinde konusalım. kv dilinde garfik parçacıklarına isimleri id özelligi ileveriyoruz. 3. satırdaki id: dugme yapmamızın nedeni bu garfik parçacıgına (nesneye) program içerisinden ulasmakiçin kullanacagımızdır. Bu dügmeye bastırıldıgında çagrılacak olan islevi app‘ın bir özelligi ile veriyoruz. Çagrılanuygulamanın tüm nesneleri, kv dili içerisinden app‘ın özelligi ile erisilir. Liste 6.2 programına bakacak olursak,kv dili içerisinde tanımlanmıs grafik parçacıklarına erismek için self.root.ids‘nin bir özelligi ile eristigimizianlarsınız. kv‘deki bir nesneye erismek için o nesnenin id ile verilmis ismini kullanıyoruz.

Kullanıcının metin girecegi bir metin kutusu, altında bir etiket ve onun altında da bir dügme bulunan bir programyazalım. Bu programı yazmadaki amacımız, metin kutusuna girilen degeri etikette görüntülemktir. Programımızı Liste6.4‘da görüyorsunuz.

Liste 6.4: main.py

1 from kivy.app import App2

3 class olayUyg(App):4

5 def metni_degistir(self):6 girilen_metin = self.root.ids.metin_girdisi.text7 self.root.ids.etiket.text='Merhaba %s !' % girilen_metin8

9 olayUyg().run()

28 Bölüm 6. Olaylar ve Popup

Page 33: Kivy Mobil Programlama - Read the Docs4 Kivy Dili: kv (kv lang) 15 ... Kivy Mobil Programlama, Sürüm 0.2 ... all users” seçili iken “Next” dügmesine tıkladı˘ gınızda

Kivy Mobil Programlama, Sürüm 0.2

Bu programla kullanacagımız kv dosyasını da Liste 6.5‘da görüyorsunuz.

Liste 6.5: olayuyg.kv

1 BoxLayout:2 orientation: 'vertical'3 TextInput:4 id: metin_girdisi5 Label:6 text: 'Adınızı yukarıya yazın...'7 id: etiket8 markup: True9 Button:

10 id: dugme11 text: 'Degistir'12 on_press: app.metni_degistir()

kv dosyasında etiket için neden markup: True dedigimizi sonra açaıklayacagız. Programımızı çalıstıralım ve üst-teki metin kutusuna adımızı yazalım. “Degistir” dügmesine tıkladıgımızda, metin kutusundaki isim etiket üzerineyazılacaktır. Programın çalısmıs halini Sekil 6.1 ‘de görüyorsunuz.

Sekil 6.1: Girilen metnin etikete yazılması

6.1 Isaret Dili (markup)

Etiket ve dügmelerde renklerin kullanımı çok kolay. Liste 6.5‘deki kv dosyasının 8. satırında markup: True bu-lunmaktadır. Bunun anlamı bu etiket metni için isaret dilinin (markup) kullanılacagıdır. Eger program içerisinde biretiket tanımlamıs olsaydık, isaret dilini etkinlestirmek için

etiket = Label(markup=True)

diyebilirdik. Ya da daha önceden tanımlanmıs bir etiket nesnesi için:

etiket.markup=True

seklinde aktiflestirebilirdik. Keske Kivy tıpkı Qt gibi standart html’yi desteklemis olsa idi, ancak ne yazıkki stan-dart html yerine kendi içerisinde birtakım isaretler vardır. Önce Liste 6.2‘deki programda kullanıcının adını etiketeyazarken kırmızı reknte yazmayı deneyelim. Bunun için 7. satırı asagıdaki gibi degistirin:

6.1. Isaret Dili (markup) 29

Page 34: Kivy Mobil Programlama - Read the Docs4 Kivy Dili: kv (kv lang) 15 ... Kivy Mobil Programlama, Sürüm 0.2 ... all users” seçili iken “Next” dügmesine tıkladı˘ gınızda

Kivy Mobil Programlama, Sürüm 0.2

self.root.ids.etiket.text='Merhaba [color=#FF0000] %s [/color] !' % girilen_metin

Artık isim kırmızı renkli olacaktır. Burada anlasılacagı gibi Kivy isaretleri [isaret] ile baslamakta ve [/isaret] ile bitirl-mektedir. Sonucu Sekil 6.2 ‘de görüyorsunuz.

Sekil 6.2: Etiketlerde renk kullanımı

Kullanabilecegimiz diger isaretler söyle:

[b][/b] Kalın metin

[i][/i] Italik metin

[u][/u] Altı çizili metin

[s][/s] Üstü çizili metin

[font=<str>][/font] Yazıtıpi belirtimi. Örnegin [font=DejaVuSerif.ttf]Merhaba Kivy![/font]

[size=<integer>][/size] Yazıtıpi boyutunu belirtir

[color=#<color>][/color] Yazı rengini degistirir

[ref=<str>][/ref] Metne bir link (bag) konulur. Bu baga tıklandıgında “ref” de verilen deger, isleve gönderilir.

[sub][/sub] Alt simge olarak gösterilir

[sup][/sup] Üst simge olarak gösterilir

Basit bir diger örnek olarak ref‘i kullanalım. Liste 6.6‘deki programda etiket üzerindeki metne tıklandıgında ekrana(komut satırına) Selam Melike ! yazacaktır.

Liste 6.6: main.py

1 # -*- coding: utf-8 -*-2

3 from kivy.app import App4 from kivy.uix.label import Label5 class olayUyg(App):6

7 def yazdir(self, nesne, deger):8 print deger9 #nesne.text = deger

10

30 Bölüm 6. Olaylar ve Popup

Page 35: Kivy Mobil Programlama - Read the Docs4 Kivy Dili: kv (kv lang) 15 ... Kivy Mobil Programlama, Sürüm 0.2 ... all users” seçili iken “Next” dügmesine tıkladı˘ gınızda

Kivy Mobil Programlama, Sürüm 0.2

11 def build(self):12 etiket = Label(text='[ref=Selam Melike !] Merhaba Fatih ![/ref]')13 etiket.markup=True14 etiket.bind(on_ref_press=self.yazdir)15 return etiket16

17 olayUyg().run()

Eger yazdir() islevini su sekilde degistirecek olursanız:

nesne.text = deger

Bu durumda, etiketteki “Merhaba Fatih !” metine tıkladıgınızda, bu metin yerine “Merhaba Melike !” görünecektir.

6.2 Popup Pencere: (popup)

Bir programcının bası sıkıstıgında hemen bir Popup pencereye basvurur. Kivy’de bu islem oldukça basit. Önce programkodu ile nasıl yapılacagına bakalım. Liste 6.7‘deki programı inceleyin.

Liste 6.7: main.py

1 # -*- coding: utf-8 -*-2

3 from kivy.app import App4 from kivy.uix.popup import Popup5 from kivy.uix.label import Label6 from kivy.uix.button import Button7

8 class olayUyg(App):9

10 def popAc(self, nesne):11 icerik=Label(text='Iste bir popup')12

13 popup = Popup(title='Popup Pencere Baslıgı',14 content=icerik,15 size_hint=(None, None), size=(200, 200))16

17 icerik.bind(on_touch_down=popup.dismiss)18 popup.open()19

20 def build(self):21 return Button(text="Popup için tıkla", on_press=self.popAc)22

23 olayUyg().run()

Bu programın ana düzeni bir tane dügmeden olusmaktadır. Bu dügmeye tıklandıgında self.popAc() islevi çag-rılmaktadır. Popup penceremiz bu islevde açılmaktadır. Öncelikle açılacak pencerenin içerigini hazırlamak gerek.Bu içerikte sadece bir etiket bulunmaktadır. Siz istediginiz bir pencere düzeni kullanarak içerigi istediginiz gibiolusturabilirsiniz. Bu içerik popup nesnesinin content parametresine verilmistir. Genelde 17. satırda bulunanbind(on_touch_down=popup.dismiss) baglantısını genellikle yapmayız. Biz burada tam bir örnek olsundiye verdik. on_touch_down olayı bir grafik parçacıgına dokunuldugunu ifade eden olaydır. Burada Popup pence-resindeki içerige dokunuldugunda pencerenin kapanmasını saglayan dismiss islevi aktiflestirilmistir. Bu programda(200,200) boyutlarında bir Popup penceresi açılır. Normalde Popup penceresinin dısındaki bir alana dokunuldugundaPopup kapanır. Eger otomatik olarak kapanmasını istemiyorsanız auto_dismiss parametresinin degerini False yap-malısınız. Yani auto_dismiss=False kullanmalısınız.

6.2. Popup Pencere: (popup) 31

Page 36: Kivy Mobil Programlama - Read the Docs4 Kivy Dili: kv (kv lang) 15 ... Kivy Mobil Programlama, Sürüm 0.2 ... all users” seçili iken “Next” dügmesine tıkladı˘ gınızda

Kivy Mobil Programlama, Sürüm 0.2

kv dili ile bir Popup olustruracagız. Biraz daha karmasık bir program olusturalım. Ana penceremizde bir etiket ol-sun, etiketin altında bir dügme ve bu dügmeye bastırılınca bir Popup açılsın. Bu Popup biraz daha farklı olsun, sankiModalView gibi davransın. Açılan Popup penceresine bir metin kutusu ve hemen yanına bir dügme ekleyelim. Popupdısarı bir yere tıklanınca kapanmasın. Üzerindeki dügmeye bastırılınca önce yapacagı isi yapsın sonra da kapan-sın. Önce kv dosyasından baslayalım. Daha önce bir kv dosyasında sadece ana pencereyi tanımlamıstık, oysaki birprogramda birden çok pencere olabilir ve bunların hepsi bir kv dosyasında tanımlanabilir. Eger birden fazla penceretanımlanacaksa, programda (bize main.py) her pencereya ait bir sınıf tanımlanmadır. Bu sınıfa ait pencere düzenikv dosyasında <sınıfAdı>: ile belirtilir. ‘deki kv Liste 6.8‘dosyasını inceleyin.

Liste 6.8: olayuyg.kv

1 <olayUyg>:2 BoxLayout:3 orientation: "vertical"4 Label:5 id: ana_pencere_etiket6 markup: True7 text: "Asagıdaki dügmeye tıklarsan [b][i]\nPopup[/i][/b] pencere açılır."8 size_hint_y: 39 Button:

10 text: "Popup Açma Dügmesi"11 on_press: app.popAc()12 size_hint_y: 113

14 <PopUpPencere>:15 size_hint: (None, None)16 size: (500, 200)17 auto_dismiss: False18 title: "Adınız:"19 #on_touch_down: self.dismiss()20 BoxLayout:21 TextInput:22 id: girilen_ad23 size_hint_x: 324 Button:25 text: "Tamam"26 size_hint_x: 127 on_press: app.popup.olayDugme(app)

Burada <olayUyg> daha önceden da kullandıgımız, ana sınıfımızın (olayUyg()) penceresini olusturmak için kul-lanılacaktır. <PopUpPencere> blogundaki tanımlar ise, programımızda PopUpPencere() isimli bir sınıf tanım-lanacak ve o sınıfın pencere düzenini olusturacaktır. Dikkat etmis iseniz, ana sınıfımıza ait grafi parçacıkların kodlarıen soldan baslamaktadır, diger bir deyisle (<olayUyg>:) ile aynı hizada baslıyor. Hemen altında BoxLayout:düzeni tanımlanıyor. Diger sınıflara ait pencere düzenlerini tanımlarken ise <sınıfAdı>: en soldan, bunun altındakikodlar bir içerden tanımlanıyor. Aslında ana pencereye ait kodlar tanımlanırken <anaSinifAdı>: yazmaya da gerekyoktur. Ancak kod okunurlugu açısından bu satırı ekliyoruz. Buna göre Liste 6.8‘deki ilk satır yazılmasa da düzgünçalısır.

Dosya yapısından sonra birazda kodlardan konusalım. Ana sınıfın penceresin olusturan <olayUyg> blogunda birkutu düzeni olusturuluyor. Bu bir etiket (size_hint_y: 3 ile pencerenin %75’ini kaplar), altında bir dügme olustu-ruluyor. Bu dügme tüm yüksekligin %25’ini kaplamaktadır. Dügmeye bastırıldıgında uygulamadaki (diger bir deyisleprogramımızda tanımlı ana sınıfımız olan olayUyg()) popAc() islevi çagrılıyor. kv dosyalarında ana sınıftakitüm nesnelere ap‘ın bir özelligi olarak erisilebilecegini tekrar hatırlatalım. Ikinci penceremiz (<PopUpPencere>)açılacak olan Popup’ın düzenini olusturmak için kullanılacaktır. Buradan programda bu düzeni kullanacak olan sı-nıfın PopUpPencere() olacagını anlıyoruz. Ilk defa bir pencerenin piksel olarak büyüklügünü nasıl belirleye-bilecegimizi görüyoruz. Bunu size ile yapıyoruz. Eger bir grafik parçacıgında size parametresini kullanırsanız,size_hint‘i mutlaka None yapmalısınız. size parametresine bir tüp atanır ve bu tüp grafik parçacıgının pik-

32 Bölüm 6. Olaylar ve Popup

Page 37: Kivy Mobil Programlama - Read the Docs4 Kivy Dili: kv (kv lang) 15 ... Kivy Mobil Programlama, Sürüm 0.2 ... all users” seçili iken “Next” dügmesine tıkladı˘ gınızda

Kivy Mobil Programlama, Sürüm 0.2

sel olarak (eni, boyu) seklindedir. Burada eni 300, boyu 100 piksel olan bir pencere açılacaktır. Daha önce oralnlarısize_hint_x ve size_hint_y olarak vermistik. Ikisini bir arada vermek için size_hint kullanabilirsiniz. Yinebu parametre bir tüp alır ve (en_oranı, boy_oranı) seklindedir. Popup pencerenin dısında bir yere tıklandıgında ka-panmasını önlemek için auto_dismiss: False satırını kullandık. Gelelim dügmeye: dügmeye bastırıldıgındaon_press uygulamanın bir özelligine erisebilmektedir. Bu özelligi ap‘dan alabiliyoruz. Fakat dügmeye bastırıldı-gında, dügmeye ait sınıftaki bir islevi çagırmak istiyoruz. Bu durumda, dügmenin sınıfını (PopUpPencere()) nasınıfın bir özellig yaparsak, o zaman dügme sınıfındaki nesnelere ap‘ı kullanarak erisebiliriz. Iste bu anlattıklarımızprogramımızın (numref:olaylar_main6) 14. satırında:

self.popup=PopUpPencere()

seklinde yazarak PopUpPencere() sınıfını ana sınıfın bir özelligi haline getiriyoruz. Bir sınıfta bir nesneyi self‘inözelligi yaparsanız, bu özellik o sınıfınızın bir özelligi olur ve o sınıf içerisinden her yerden erisilebilir. Böylelikle‘ PopUpPencere() sınıfına ait özelliklere, ana sınıf içerisinden self.popup‘ın bir özelligi olarak erisilebi-lir. kv dosyasında ana sınıf app olarak erisiliyordu, bu durumda app.popup nesnesi PopUpPencere() sını-fını temsil edecektir. Eger PopUpPencere() sınıfının içerisinden ana sınıfımıza ait özelliklere erismek istyorsak,PopUpPencere()‘da çagırdıgımız islevlere ana sınıfın kendisini argüman olarak göndermemiz gerekir. Eger prog-ram kodundan çagırıyorsak self‘i, kv dosyasında çagırıyorsak ap‘ı argüman olarak göndermeliyiz. Elbette islevdebu argümanı alacak bir parametre bulunmalıdır. Liste 6.8‘dosyasında Popup penceredeki dügmeye bastırıldıgındaapp.popup.olayDugme(app) islevini çagırdık. PopUpPencere() sınıfında tanımlanacak olayDugme()islevi app‘ı alacaktır. Bunu Liste 6.9‘deki 6. satırda görüyorsunuz.

Liste 6.8 kv dosyasını kullanacak olan programımız Liste 6.9‘da yazılmstır.

Liste 6.9: main.py

1 from kivy.app import App2 from kivy.uix.popup import Popup3

4 class PopUpPencere(Popup):5

6 def olayDugme(self, uyg):7 ad=self.ids.girilen_ad.text8 uyg.root.ids.ana_pencere_etiket.text="Merhaba %s !" % ad9 self.dismiss()

10

11 class olayUyg(App):12

13 def popAc(self):14 self.popup=PopUpPencere()15 self.popup.open()16

17 olayUyg().run()

Bu programda olayDugme() isevi ana penceredeki etikete erisiyor ve Popup’da girilen ismi ana pencerenin etiketineyazıyor. kv dosyasındaki on_press: app.popup.olayDugme(app) satırı, ana sınıfı (app) bu iseleve gönde-riyor, bu islevin uyg parametresine atanıyor. Böylelikle uyg.root.ids kullanılarak ana penceredeki tanımlanmısgrafik parçacıklarına erisebiliyoruz.

Programımızı çalıstırıp alttaki dügmeye bastırdıgımızda elde edecegimiz görüntü Sekil 6.3‘deki gibi olacaktır.

Adımızı yazıp “Tamam” dügmesine bastırdıgımızda Popup kapanacak ve Sekil 6.4‘deki gibi olacaktır.

Artık basit bir uygulama yazabiliriz. Su can sıkıcı ve hiçbir ise yaramayan Metin Düzenleyici yazacak kadar bilgisahibi olduk.

6.2. Popup Pencere: (popup) 33

Page 38: Kivy Mobil Programlama - Read the Docs4 Kivy Dili: kv (kv lang) 15 ... Kivy Mobil Programlama, Sürüm 0.2 ... all users” seçili iken “Next” dügmesine tıkladı˘ gınızda

Kivy Mobil Programlama, Sürüm 0.2

Sekil 6.3: Popup’ın açılması

Sekil 6.4: Popup isevinden Ana Penceredeki metnin degistirilmesi.

34 Bölüm 6. Olaylar ve Popup

Page 39: Kivy Mobil Programlama - Read the Docs4 Kivy Dili: kv (kv lang) 15 ... Kivy Mobil Programlama, Sürüm 0.2 ... all users” seçili iken “Next” dügmesine tıkladı˘ gınızda

BÖLÜM 7

Metin Düzenleyici

Birçok yeni programcı, programların çok basit sekilde hazırlanabilecegini düsünür. Oysa ki en küçük programda bileçok fazla düslünülecek ve yapılacak is vardır. Bu bölümde basit bir metin düzenleyici yapacagız. Elbette yapacagımızmetin düzenleyici üretim açamlı olmayacaktır. Sadece bir program yazılırken, programcıların nelere dikkat etmelerigerektigi, nereleri düsünmeleri gerektigine bir ısık tutacagız. Basit bir metin düzenleyici yazmak için ne kadar çokyapılacak is oldugunu göreceksiniz. Bir programı yazmaya baslayınca, düsünmenin sınırı ve yapılacakların sonu ol-madıgını göreceksiniz. Biz burada bir yol açalım, gerisini size bırakacagız.

7.1 Ana Pencere

Buradaki metin düzenleyici basitçe bir metin alanı ve kullanıcıya dosyasını açıp kaydedebilecegi birkaç seçenek sun-maktan ibaret (tamamı bu degildir elbette) olacak. O halde öncelikle ana penceremizi hazırlayalım, bunun için simdilikmetin alanımızı ve altına islem yapmayan birkaç dügme koyalım. Daha sonra bu dügmelere islerlik kazandıracagız.main.py dosyasını Liste 7.1‘deki gibi yazalım.

Liste 7.1: main.py

1 # -*- coding: utf-8 -*-2

3 import os, sys4 from kivy.uix.label import Label5 from kivy.app import App6 from kivy.uix.popup import Popup7

8 class metinDuzenleyici(App):9

10 def build(self):11 pass12

13

14 metinDuzenleyici().run()

35

Page 40: Kivy Mobil Programlama - Read the Docs4 Kivy Dili: kv (kv lang) 15 ... Kivy Mobil Programlama, Sürüm 0.2 ... all users” seçili iken “Next” dügmesine tıkladı˘ gınızda

Kivy Mobil Programlama, Sürüm 0.2

Bu programda bilmedigimiz hiçbirsey yok. os ve sys modüllerini neden içerdigimizi ileride göreceksiniz. Simdi de,bu program tarafından kullanılacak kv dosyasını Liste 7.2‘deki gibi yazalım:

Liste 7.2: metinduzenleyici.kv

1 <metinDuzenleyici>:2 BoxLayout:3 orientation: "vertical"4 exit_on_escape: False5 TextInput:6 size_hint_y: 907 id: metin8 multiline: True9

10 BoxLayout:11 size_hint_y: 1012 Button:13 text: "Aç"14 on_press: pass15 Button:16 text: "Kaydet"17 on_press: pass18 Button:19 text: "Farklı Kaydet"20 on_press: pass21 Button:22 text: "Yeni"23 on_press: pass

Bu dosyada bilmedigimiz sadece TextInput parçacıgının multiline özelligine True degerinin atanmıs olmasıdır.TextInput parçacıgını

metin = TextInput(multiline=True)

seklinde tanımlayacak olursak, çok satırlı bir metin girdi alanı elde etmis oluruz. TextInput parçacıgı ön tanımlıolarak tek satırdan olusur, multiline özelligine True degeri atamkla çok satırlı bir metin giris alanı elde etmisoluruz ki, bir metin düzenleyicinin metin yazılacak alanı tam da bu yaptıgımız gibidir.

main.py programı çalıstırdıgımızda metin düzenleyicimizin penceresi Sonucu Sekil 7.1 ‘deki gibi açılacaktır.

Simdi yukarıdaki dügmelere tıklayın bakalım dosya açacak mı, dosyanızı kaydedecek mi? Sizce olur mu? Neden ol-masın ki? Ben dügmeyi koydum, program da gitsin dosyamı kaydedecegini anlasın ve kaydetsin. Benzer cümleleriher sınıfımda kullanırım. Ancak ne yazıkki bu programları yazanlar, bizim koydugumuz dügmelerin (ya da menülerin)üzerindeki metinlere bakarak, ne is yapmak istedigimizi anlamayacak kadar becereksizler. Öyle mi? Elbette degil. Birdügme koyduysanız, ona tıklandıgında ne yapılması gerektigini siz yazacaksınız, bir baskası degil. Bu kadar söylen-dikten sonra gelin, bu dügmelere islerlik kazandıralım. Öncelikle “Farklı Kaydet” dügmesinden baslayalım. Nedenmi? Çünkü “Kaydet” dedgimizde, daha önceden bir dosya adı verilmemisse “Farklı Kaydet” çagrılacaktır.

7.2 Farklı Kaydet

Bir dosyayı kaydetmek için, öncelikle kaydedilecek klasörün belirtilmesi ve daha sonra da dosya adının girilmesi ge-rekir. Eger kullanıcıya basitçe bir metin kurtusu saglayıp buraya dosyanın tam patikasını yazmasını isterseniz (örneginC:\dosyalarım\odevlerim\fizik\newton.txt seklinde), kusura bakmayın ama programınızı kimse kul-lanmaz. 1990’lı yıllarda olsaydınız buna kimse itirtaz etmezdi ancak simdi GUI (Grafik Kullanıcı Arayüzü) icat edildi.O halde klasörler arasında gezinti yapabilecek bir arayüze ihtiyacımız var. Bun kendiniz yapabilirsiniz. Nasıl mı? os.listdir()‘i biliyorsunuz. Her bir elemanı ızgara düzenine bir dügme olarak yerlestirip gezinti saglayabilirsiniz.

36 Bölüm 7. Metin Düzenleyici

Page 41: Kivy Mobil Programlama - Read the Docs4 Kivy Dili: kv (kv lang) 15 ... Kivy Mobil Programlama, Sürüm 0.2 ... all users” seçili iken “Next” dügmesine tıkladı˘ gınızda

Kivy Mobil Programlama, Sürüm 0.2

Sekil 7.1: Metin Düzenleyicimiz Kullanıma Hazır :-)

7.2. Farklı Kaydet 37

Page 42: Kivy Mobil Programlama - Read the Docs4 Kivy Dili: kv (kv lang) 15 ... Kivy Mobil Programlama, Sürüm 0.2 ... all users” seçili iken “Next” dügmesine tıkladı˘ gınızda

Kivy Mobil Programlama, Sürüm 0.2

Ama bunu yapmayın. Çünkü Kivy gelistiricileri bizim için daha iyisini yapmıs: FileChooserListView. Bu grafik par-çacıgı bize dizinler arası gezinti yapmamızı saglayacak bir araç sunmaktadır. Bu parçacıgın filters özelligi sayesinde,hangi dosyaları liseteleyecigimizi de belirtebiliyoruz (asagıda ['*.*'] kodu tüm dosyaların listelenecegini göster-mektedir. Üstelik bir seçim yaptıgımızda on_selection olayı sayesinde, seçim ile ilgili islemlerimizi yapabiliyoruz. Ohalde bu parçacıgı en üste koyalım, altına bir adet dosya adının yazılabilecegi metin kutusu, onun altına da iki adetdügme: “Kaydet”, “Vazgeç”. O halde metin düzenleyicimizin pencerelerinin olusturuldugu metinduzenleyici.kv dosyasına asagıdaki gibi yeni bir form ekleyelim:

Liste 7.3: FakrliKaydetForm

1 <farkliKaydetForm>:2 title: "Dosya Kaydet"3 size_hint: (.9, .9)4 BoxLayout:5 orientation: 'vertical'6

7 FileChooserListView:8 size_hint_y: 809 id: dosya_secim

10 filters: ['*.*']11 path: app.son_patika12 on_selection: pass13

14 BoxLayout:15 size_hint_y: 1016 Label:17 text: "Dosya Adı:"18 size_hint_x: 2019 TextInput:20 id: dosya_adi21 size_hint_x: 8022

23 BoxLayout:24 size_hint_y: 1025 Button:26 text: "Kaydet"27 on_press: pass28 Button:29 text: "Vazgeç"30 on_press: root.dismiss()

Bu formu kullanacak bir sınıf tanımlamak gerekiyor. Bunu class metinDuzenleyici(App) satırından önceasagıdaki kodları ekleyerek yapabiliriz:

class farkliKaydetForm(Popup):pass

Dosya ismini ve kaydedildigi patikayı takip etmemiz gerekmektedir. Nedenini söyle açıklayabiliriz, eger bir dosyaaçılmıs (ya da bir isimle kaydedilmis) ise, dosya ismi var olacagından tekrar kaydedilmesi sırasında bı dosya isminikullanmamız gerekmektedir. Dosya ismi gerekli ise, kaydedildigi klasör de gereklidir. O halde tüm programımız içe-risinde dosya ismi ve patikayı kullanabilecegimizden, build() islevine asagıdaki satırları eklememiz gerekecek.

self.son_patika= os.getcwd()self.son_dosya=''

Bu satırları ekledikten sonra build() islevindeki pass ifadesine gerek kalmayacak.

Sanırım main.py programının basında os modülünü çagırma nedenimizi anladınız. Burada son patika ön tanımlı

38 Bölüm 7. Metin Düzenleyici

Page 43: Kivy Mobil Programlama - Read the Docs4 Kivy Dili: kv (kv lang) 15 ... Kivy Mobil Programlama, Sürüm 0.2 ... all users” seçili iken “Next” dügmesine tıkladı˘ gınızda

Kivy Mobil Programlama, Sürüm 0.2

olarak programın çalıstıgı patikayı göstermektedir, son dosya ise bos bir cümledir, yani dosya adı yoktur.

Ana pencerede “Farklı Kaydet” dügmesine tıklandıgında farkliKaydetForm‘nun açılabilmesi için, üzerinde“Farklı Kaydet” yazan dügmeye tıklandıgında bir islevin çagrılması ve bu islev altından da bu formu gösterebilme-miz gerekiyor. O halde bu dügmenin on_press özelligini farkliKaydetDialog() islevini çagıracak sekildeasagıdaki gibi degistirelim (Liste 7.2‘deki 18, 19 ve 20. satırlar):

Button:text: "Farklı Kaydet"on_press: app.farkliKaydetDialog()

Isimiz henüz bitmedi, çünükü dügmeye tıklandıgında çagrılacak olan islevi yazmadık, bunun için build() islevindenhemen önce asagıdaki islevi tanımlayalım:

def farkliKaydetDialog(self):form = farkliKaydetForm()form.open()

Artık “Farklı Kaydet” dügmesine tıkladıgımzda yeni bir pencere açılmaktadır. Açılacak olan pencereyi Sekil 7.2 ‘degörüyorsunuz:

Sekil 7.2: Farklı Kaydet Penceresi

Peki bu pencere su anda ne is yapar? Sadece dosya ve klasörleri listeler (bunuda biz yapmadık FakrliKaydetForm‘de7. satırda tanımladıgımız FileChooserListView parçacıgı yapıyor). Haa birde çok büyük bir is olan “Vazgeç”dügmesine tıklandıgında pencere kapanıyor. Sanırım bunu bizden baska basarabilecek kimse de yok :-). Peki bu nasılgerçeklesiyor? Pencerenin kapanmasını bizim yazdıgımız kod saglamkta, saka yapmıyorum :-) Peki nersi? Yanılmı-yorsam (yanılıyorsam lütfen beni uyarın!), FakrliKaydetForm‘deki 30. satır bu isi yapıyor olmalı.

7.2. Farklı Kaydet 39

Page 44: Kivy Mobil Programlama - Read the Docs4 Kivy Dili: kv (kv lang) 15 ... Kivy Mobil Programlama, Sürüm 0.2 ... all users” seçili iken “Next” dügmesine tıkladı˘ gınızda

Kivy Mobil Programlama, Sürüm 0.2

Az zamanda çok isler basardıgımızı söylemek isterdim, ancak gerçek bu degil. Daha henüz ise yarar birsey yap-madık. Öncelikle FileChooserListView parçacıgının gösterdigi dosya isimleri üzerine tıklandıgında (digerbir deyisle var olan dosya ismini seçip bu dosya üzerine kaydetmek isteyebilir, aman dikkat !! çok tehlikeli,kaydetmeden önce onay almalısınız, bunu size bırakıyoruz) bu dosya isminin dosya adı yazılacak olan (id‘sidosya_adi olan TextInput parçacıgı) metin kutusunda belirmelidir. Bunu nasıl yapacagız? Daha önce demistik yaon_selection özelligi ile. Bu özelligi dosya seçimi isleminden sonra çagrılacak olan isleve baglayabiliriz. Bununiçin FileChooserListView parçacıgının on_selection özelligini asagıdaki gibi degistirin (FakrliKaydet-Form‘de 12. satırı asagıdaki gibi degistirin):

on_selection: app.farkliKaydetSecim(root)

Burada ne yapılıyor? Her sonunun cevabını verdik te bunun cevabını mı esirgeyelim? Burada yapılan is, formun ken-disini uygulamanın farkliKaydetSecim() islevine argüman olarak göndermek. Gerisini bu islev halletmektedir.O zaman bu iselvi yazmalıyız. build()‘den hemen önce asagıdaki islevi tanımlayalım:

def farkliKaydetSecim(self, form):secilen_dosya=form.ids.dosya_secim.selectionif secilen_dosya:

if len(secilen_dosya)>0:dosyaAdi=os.path.split(secilen_dosya[0])[1]form.ids.dosya_adi.text=dosyaAdi

Bu isleve farkliKaydetForm‘nun kendisi argüman olarak geliyordu, bunu form degiskenine aktardık.FileChooserListView nesneninden seçilen dosyayı selection özelligi ile alabaliriz. Bu bize seçilen tümdosyaları (çoklu seçim yapılabilir, multiselect özelliginin degeri True yapılarak). Ön tanımlı olarark sadece bir dosyaseçilebildiginden, ilk dosyayı patika ve dosya adı olarak ayırdıktan sonra yaptıgımız is dosya adını formumuzda ids’sidosya_adi olan metin kutusunda göstermektir.

Simdi gelelim “Kaydet” dügmesine tıklandıgında yapılacak olan ise: formadki metin kutusundan dosya adını alacak vediske yazma islemi gerçeklestirilecek. Diske yazma islemini farklı bir islevde yapacagız, çünkü ana pencerede “Kay-det” dügmesine tıklandıgında da bu islevi çagıracagız. Önce “Kaydet” dügmesine tıklandıgında çagrılacak olan islevibelirtmeliyiz, ardındanda bu pencereyi kapatmalıyız. O halde FakrliKaydetForm deki 27. satırı su sekilde degistirelim:

on_press: app.farkiKaydetIslevi(root); root.dismiss()

Gelelim farkiKaydetIslevi() islevine: bu islevi build() den hemen önce su sekilde tanımlayabiliriz:

def farkiKaydetIslevi(self, form):self.son_patika=form.ids.dosya_secim.pathself.son_dosya=form.ids.dosya_adi.textself.dosyaKaydet()

Bu basit islevde, formda dosyanın patikası alınıp self.son_patika degiskenine aktarılıyor. Benzer sekildeself.son_dosya degiskenine formdaki ids’si dosya_adi olan metin kutusundaki dosya adı aktarılıyor. Sonolarak dosyaKaydet() islevi çagrılıyor. Simdi de bu islevi yazalım (build() den hemen önce):

def dosyaKaydet(self):if not self.son_dosya:

self.hataGoster("Dosya adı verdiginizden eminmisiniz?")else:

try:dosya_tam_isim = os.path.join(self.son_patika, self.son_dosya)F=open(dosya_tam_isim, 'w')F.write(self.root.ids.metin.text)F.close()

except:

40 Bölüm 7. Metin Düzenleyici

Page 45: Kivy Mobil Programlama - Read the Docs4 Kivy Dili: kv (kv lang) 15 ... Kivy Mobil Programlama, Sürüm 0.2 ... all users” seçili iken “Next” dügmesine tıkladı˘ gınızda

Kivy Mobil Programlama, Sürüm 0.2

self.hataGoster("Dosyayı yazamadım. Nedeni: [color=#FF0000]%s[/color]"% str(sys.exc_info()[1][1]))

Tahmin ettiginizden daha karmasık degilmi? Bir defa hataGoster() diye bir islevin tanımlanması gerekiyor. Egerkullanıcı dosya adı yamamıs ise (formdaki ids’si dosya_adi olan metin kutusu bos ise), kullanıcıya popup pencereile bunu bildirmeliyiz. Bunu hataGoster() islevini tanımlayarak yapabiliriz. Eger dosya ismi var ise, yazma is-lemi gerçeklestirilecek. Bu ise biraz tehlikeli bir is, öncelikle dosyanın tam adı olusturuluyor (self.son_patikave self.son_dosya degiskenlerinin degerleri os.path.join() ile). Son olarak dosya açılıyor ve üzerine ya-zılıyor. Bunu try: blogunda yaptık, çünkü dosya bir sebepten dolayı yazılamayabilir. Nasıl bir sebep olabilir ki?Söyle: disk dolu olabilir, dosyaya yazma yetkisi olmayabilir, klasöre yazma yetkisi olmayabilir, böyle bir disk olma-yabilir .... Her ne sebeptenolursa olsun, dosya yazılamadıgında programın kırılmayacak ve except: blogu isletilerekdosyanın yazılamama sebebi kullanıcıla iletilecek. Bu da yine hataGoster() islevi çagrılarak yapılıyor. Peki buhataGoster() islevi kimin nesi? Kimsenin birseyi degil! Sadece asagıdaki kodlardan olusan gariban bir islev:

def hataGoster(self, hata):icerik=Label(text=hata, markup=True)popup = Popup(title='Yapamadım !', content=icerik)popup.size_hint = (0.7,0.7)icerik.bind(on_touch_down=popup.dismiss)popup.open()

Bu islevi build() den hemen önce tanımlayabilirsiniz.

Aslında düzenlenen bir dosyayı bu sekilde dogrudan yazmak akıllı bir programcını yapacagı is degildir. Eger birnedenden dolayı dosya yazılamaz ise, program sonlanır ve kullanıcının önceki yeazdıkları da dahil olmak üzere kay-bolur. Bu sekilde kaydedilirken bir problem çıkması durumunda çogu zaman bos bir dosya elde edilir. Olası durumlarıkontrol ettik, ancak birde kontrol edemedigimiz durumlar var. Öregin tam yazma asamasında, elektrik kesilirse! Budurumda kullanıcıya bos bir dosya verir bol küfür alırsınız. Tüm programlama dillerinde diske yazma islemi dogru-dan gerçeklesmez, belirli bir buffer büyüklügü vardır bu doldugunda diske yazılır daha sonra buffer’in tekrar dolmasıbeklenir (hızdan tasaffur, disk kullanımından tasarruf gibi nedenlerle). Bu nedenle dosya kapatılana kadar (close())yazma isleminden emin olmazsınız [her harfi yazdıktan sonra flush() kullanmamıssanız :-)]. En iyisi önce dosyayıgeçici olarak yazmak, daha sonra dosya adını degistirmektir. Örnegin:

F=open(dosya_tam_isim+'~', 'w')F.write(self.root.ids.metin.text)F.close()os.rename(dosya_tam_isim+'~', dosya_tam_isim)

Burada da yine dikkat etmemiz gereken sey, dosya_tam_isim dosyasının yazılabilir oldugundan emin olmaktır.Bunuda

os.access(dosya_tam_isim, os.W_OK)

ile kontrol edebilirsiniz. “Farklı Kaydet” bitti. Simdi sıra geldi “Kaydet”e

7.3 Kaydet

Bu sandıgınızdan daha kolay. Çünkü birçok isi, “Farklı Kaydet”de yaptık. Öncelikle ana pencerede “Kaydet” düg-mesinde tıklandıgında bir islev çagırmalıyız ve tüm isi bu iselve yaptırtmalıyız. Bunun için Liste 7.2‘deki 17. satırıasagıdaki gibi degistirelim:

on_press: app.dosyaKaydetIslevi()

Simdi de bu islevi yazalım, build() den hemen önce su sekilde tanımlayabiliriz:

7.3. Kaydet 41

Page 46: Kivy Mobil Programlama - Read the Docs4 Kivy Dili: kv (kv lang) 15 ... Kivy Mobil Programlama, Sürüm 0.2 ... all users” seçili iken “Next” dügmesine tıkladı˘ gınızda

Kivy Mobil Programlama, Sürüm 0.2

def dosyaKaydetIslevi(self):if self.son_dosya: self.dosyaKaydet()else: self.farkliKaydetDialog()

Burada dikkat ederseniz, öncelikle dosya adının olup olmadıgına bakılıyor. Dosya adı var ise dogrudakdosyaKaydet() islevi çagrılıyor. Bunu daha önce yazmıstık. Dosya adı yok ise, farkliKaydetDialog()islevi çagrılıyor. Bunu da “Farklı Kaydet” kesitinde yazmıstık. Çok kolaymıs degil mi?

7.4 Aç

Var olan bir dosyayı açmak için kullanacagımız bu dügme, eger dikkatli olmazsak basımıza is açabilir. Sebep? Egerdüzenlenmekte olan bir dosya kaydedilmeden, baska bir dosya açılmaya kalkısılırsa ve siz bunu kullanıcya bildirme-misseniz, bu durumda istenmedik laflar isitebilirsiniz (merak etmeyin, nasıl olas programı kullanan uzakta olacagındanduymazsınız). Isitmeseniz bile buna dikkat etmek iyi bir programcı oldugunuzu gösterir. Peki bir metnin degistigini vekaydedildigini nasıl anlayacagız? Bunu bizim için yapacak bir kimse yok. Bu nedenle basımızın çaresine bakmalıyız.

Önce metnin degisip degismedigini bilmemiz gerekiyor, bunu tanımlayacagımız self.metin_degisti degiskeniile takip edebiliriz. O halde build() islevi altına asagıdaki satırları ekleyelim:

self.metin_degisti=False

Degerini False yaptık çünkü baslangıçta bir netnin içerigi degismemistir. Metin degistikçe bunun degerini True,kaydettikçe degerini False yapmalıyız. Önce kaydettigimizde degerin False olması için dosyaKaydet() isle-vindeki F.close() satırından hemen sonra su satırı eklemeliyiz:

self.metin_degisti=False

Bu tamam, peki metnin degistigini nasıl anlayacagız? Bunu bize Kivy söyleyebilir. TextInput perçacıgınıntext‘ine bir islev baglarsak, metin degistikçe bu islev çagrılır. O halde build() islevinin altına asagıdaki satır-ları eklemeliyiz:

self.root.ids.metin.bind(text=self.metinDegisti)self.ilkAcilis=True

Buradaki self.ilkAcilis degiskeni, programın ilk açlıp açılmadıgını takip etmek için gereklidir. ÇünküTextInput nesnesi olusturulur olusturulmaz self.metinDegisti islevi çagrılır. Buda programın ilkaçılıp açılmadıgına göre self.metin_degisti degiskeninin degerini degistirmelidir. Bize gerekli olanmetinDegisti() islevini build() den hemen önce söyle tanımlayabiliriz:

def metinDegisti(self, nesne, deger):if self.ilkAcilis: self.ilkAcilis=Falseelse: self.metin_degisti=True

Eger programımız ilk açılısta bu islev çagrılıyorsa, if self.ilkAcilis degiskeninin degeri False yapılıyor,sonraki çagrılıslarda (metin girisi yapılır veya dosya okunursa), self.metin_degisti degiskeninin degeri Trueyapılıyor.

Su ana kadar dosya açma ile ilgili birsey yapmadık, sadece metnin degisip degismedigini takip ettik. Önce-likle dosya açılma islemini tıpkı “Kaydet”de oldugu gibi, bir dizin tarayıcı olusturmamız gerekiyor. Bunu yineFileChooserListView ile yapabiliriz. Bunun için bir form ve bu formu olusturacak kv kodlarına ihtiyacımızvar. metinduzenleyici.kv dosyasına asagıdaki kodu ekleyin:

42 Bölüm 7. Metin Düzenleyici

Page 47: Kivy Mobil Programlama - Read the Docs4 Kivy Dili: kv (kv lang) 15 ... Kivy Mobil Programlama, Sürüm 0.2 ... all users” seçili iken “Next” dügmesine tıkladı˘ gınızda

Kivy Mobil Programlama, Sürüm 0.2

Liste 7.4: dosyaAcForm

1 <dosyaAcForm>:2 title: "Dosya Aç"3 size_hint: (.9, .9)4 BoxLayout:5 orientation: 'vertical'6

7 FileChooserListView:8 size_hint_y: 909 id: dosya_secim

10 filters: ['*.*']11 path: app.son_patika12

13 BoxLayout:14 size_hint_y: 1015 Button:16 text: "Aç"17 on_press: app.dosyaOku(dosya_secim); root.dismiss()18 Button:19 text: "Vazgeç"20 on_press: root.dismiss()

Bu kv formunu kullanacak sınıfı tanımlamak gerekiyor. Bunu class metinDuzenleyici(App) satırındanönce asagıdaki kodları ekleyerek yapabiliriz:

class dosyaAcForm(Popup):pass

Simdide “Aç” dügmesine tıklandıgında çagrılacak olan islevi kv dosyasında belirtelim. Bunun için Liste 7.2‘deki 14.satırı asagıdaki satırı söyle degistirelim:

on_press: app.dosyaAcIsleviDialog()

Simdi de bu islevi tanımlamak gerekiyor. build() den hemen önce islevimizi söyle tanımlayabiliriz:

def dosyaAcIsleviDialog(self):if self.metin_degisti:

self.hataGoster("Dosya kaydedilmedi. Önce kaydedin.")else:

self.dosyaAcDialog()

Bu islev anladıgınız üzere, dosyanın degisip degismedigini kontrol ediyor. Eger kaydedilmemisse, kaydetmesi içinuyarıyor. Kaydedilmis ise, dosyaAcDialog() islevini çagırıyor. O halde bu isevi de build() den hemen önce susekilde tanımlayabiliriz:

def dosyaAcDialog(self):form = dosyaAcForm()form.open()

“Dosya Aç” formu açıldıgında allta iki adet dügmemiz olacak. “Vazgeç” dügmesine tıklandıgında form kapanacak.“Aç” dügmesine tıklandıgında ise, dosyaOku() islevi çagrılıyor (metinduzenleyici.kv dosyasına ekledi-gimiz Liste 7.4‘deki 17. satır). Bu islev oldukça basit, sadece seçilen dosyayı gidip okuması gerekiyor. Bunu dabuild() den hemen önce asagıdaki gibi tanımlayabiliriz:

def dosyaOku(self, dosya_secim):if dosya_secim.selection:

7.4. Aç 43

Page 48: Kivy Mobil Programlama - Read the Docs4 Kivy Dili: kv (kv lang) 15 ... Kivy Mobil Programlama, Sürüm 0.2 ... all users” seçili iken “Next” dügmesine tıkladı˘ gınızda

Kivy Mobil Programlama, Sürüm 0.2

if len(dosya_secim.selection)>0:(self.son_patika,self.son_dosya)=os.path.split(dosya_secim.selection[0])try:

self.root.ids.metin.text=open(dosya_secim.selection[0]).read()self.root.ids.metin.cursor=self.root.ids.metin.get_cursor_from_

→˓index(0)self.metin_degisti=False

except:self.hataGoster("Dosyayı Okuyamadım. Nedeni: [color=#FF0000]%s[/color]

→˓"% str(sys.exc_info()[1][1]))

else:self.hataGoster("Dosya seçtiginizden eminmisiniz?")

Bu islevdeki hemen herseyi daha önce anlattık. Simdi bir sorunumuz var (bitti mi ki?). Kullanıcı dosyayı düzenle-yip yeni dosya açmak istediginde sadece “Dosya kaydedilmedi. Önce kaydedin.” uyarısında bulunuyor. Oysa ki iyibir program dosyayı açmadan önce dosyanın degistigini uyarmalı ve kullanıcıya kaydedip kaydetmeyecegi ile ilgiliseçenek sunmalıdır. Bunun için yeni bir form tasarlamalıyız. Bu form sedece mevcut dosyanın kaydedilip kaydede-dilmemesini veya dosya açma isleminden vazgeçilmesini önermelidir. Böyle bir formu metinduzenleyici.kvdosyasına asagıdaki satırları ekleyerek tasarlayabiliriz:

Liste 7.5: dosyaKaydedilmediForm

1 <dosyaKaydedilmediForm>:2 title: 'Mevcut Dosya Kaydedilmedi'3 size_hint: (.9, .9)4 BoxLayout:5 orientation: 'vertical'6

7 Label:8 size_hint_y: 909 text: "Çalıstıgınız dosya kaydedilmedi. Kayıt yapılsın mı?"

10

11 BoxLayout:12 size_hint_y: 1013 Button:14 text: "Kaydet"15 on_press: app.dosyaKayedilmediKaydet(root)16 Button:17 text: "Hayır"18 on_press: app.dosyaAcDialog(); root.dismiss()19 Button:20 text: "Vazgeç"21 on_press: root.dismiss()

Bu kv formunu kullanacak sınıfımızı class metinDuzenleyici(App) satırından önce asagıdaki kodları ekle-yerek yazabiliriz:

class dosyaKaydedilmediForm(Popup):pass

Peki bu form’u nerede çagıracagız? Bildiniz degilmi? Yoksa bilemediniz mi? Bilemeyenlere hemen söyle-yeyim, dosyaAcIsleviDialog() islevinde dosya açmak istediginde “Dosya kaydedilmedi. Önce kayde-din.” uyarısında bulunuyorduk ya iste burada. Yani bu uyarının yapıldıgı satırın yerine yazmalıyız. O haldedosyaAcIsleviDialog() islevini asagıdaki gibi degistirmeliyiz:

44 Bölüm 7. Metin Düzenleyici

Page 49: Kivy Mobil Programlama - Read the Docs4 Kivy Dili: kv (kv lang) 15 ... Kivy Mobil Programlama, Sürüm 0.2 ... all users” seçili iken “Next” dügmesine tıkladı˘ gınızda

Kivy Mobil Programlama, Sürüm 0.2

def dosyaAcIsleviDialog(self):if self.metin_degisti:

kaydedilmedi_form = dosyaKaydedilmediForm()kaydedilmedi_form.open()

else:self.dosyaAcDialog()

Dosyanın kaydedilmedigi durumda dosya açmaya kalkısıldıgında kullandıgımız form’da kullanıcı “Kaydet” dügme-sine tıklarsa dosyamızın kaydedilmesi için dosyaKayedilmediKaydet() islevi çagrılmaktadır (Liste 7.5‘deki15. satır). Bu islevi build() den önce su sekilde yazabiliriz:

def dosyaKayedilmediKaydet(self, kok):if self.son_dosya:

self.dosyaKaydet()kok.dismiss()self.dosyaAcDialog()

else:kok.dismiss()self.hataGoster("Dosya adı yok. 'Farklı Kaydet' kullanarak kaydetmelisiniz.")

Burada benimde hosalsamadıgım ve birçok kullanıcı için de garip gelecek bir durum var. Eger dosya daha öncekaydedilmemis ise, dosya adı (self.son_dosya degiskeninde saklanan) olmayacaktır ve bu durumda kullanı-cıya “Farklı Kaydet”i kullanarak kaydetmesi önerisi sunulmaktadır. Oysa ki bunun yerine dogrudan farklı kaydetdialogu (farkliKaydetDialog()) çagrılmalıydı. Bu Kivy’de olmadı. Bunu yapabilmemiz için, bu diyalog açıl-dıktan sonra, programın kullanıcıdan tepki gelene kadar hiçbir is yapmaması gerekir (diger bir deyisle program akısıdurdurulmalıdır). Kivy’de ne yazıkki bu yok, en azından ben bilmiyorum.

7.5 Yeni

Kullanıcı bir dosya üzerinde çalısırken yeni bir dosya açmak isteyebilir. Bunun için ana penceremizin sag alt tarafyabunulnan “Yeni” dügmesine tıklayacak. Simdi bunun üzerinde çalısalım. Yapacagımız isi söyle özetleyebiliriz: ilkolarak mevcut dosya degistirilmis ve henüz kaydedilmemis ise, bunu kullanıcıya bildirmemiz gerekir, daha sonra yenidosya olusturma islemine geçecegiz. Öncelikle ana penceredeki “Yeni” dügmesine tıklandıgında çagrılacak olan islevibelirtmek için metinduzenleyici.kv dosyasındaki (Liste 7.2) 23. satırı su sekilde degistirmemiz gerekmektedir:

on_press: app.yeniDosyaAcIslevi()

Bu islevi de build() den önce su sekilde yazabiliriz:

def yeniDosyaAcIslevi(self):if self.metin_degisti:

form = yeniDosyaForm()form.open()

else:self.yeniDosyaAc()

Burada metnin degismesi durumumnda yeni bir dialog (form) açılacak. Bu forma ait kv kodlarınımetinduzenleyici.kv dosyasına asagıdaki satırları ekleyerek olusturabiliriz:

Liste 7.6: yeniDosyaForm

1 <yeniDosyaForm>:2 title: 'Mevcut Dosya Kaydedilmedi'3 size_hint: (.8, .8)4 BoxLayout:

7.5. Yeni 45

Page 50: Kivy Mobil Programlama - Read the Docs4 Kivy Dili: kv (kv lang) 15 ... Kivy Mobil Programlama, Sürüm 0.2 ... all users” seçili iken “Next” dügmesine tıkladı˘ gınızda

Kivy Mobil Programlama, Sürüm 0.2

5 orientation: 'vertical'6 Label:7 size_hint_y: 908 text: "Çalıstıgınız dosya kaydedilmedi. Yeni dosya açmak istediginizden

→˓emin misiniz?"9 BoxLayout:

10 size_hint_y: 1011 Button:12 text: "Vazgeç"13 on_press: root.dismiss()14 Button:15 text: "Evet"16 on_press: app.yeniDosyaAc(); root.dismiss()

Bu kv kodlarını kullanacak olan yeniDosyaForm() sınıfınıda class metinDuzenleyici(App) satırındanönce asagıdaki kodları ekleyerek yazabiliriz:

class yeniDosyaForm(Popup):pass

yeniDosyaForm’unda kullanıcı yeni dosya açmaktan vazgeçerse zaten form kapanıyor, eger kaydetmek için “Evet”dügmesine tıklarsa, yeniDosyaAc() islevi çagrılıyor. Yeni dosya açma islevini build() den hemen önce söyleyazabiliriz.

def yeniDosyaAc(self):self.root.ids.metin.text=""self.son_dosya=""

En kolayı bu oldu sanırım, self.son_dosya degiskeninin degeri ile metin alanının degerini bos cümle yaparakyeni dosyayı olusturmus olduk.

7.6 Çıkmadan Önce

Henüz bitmedi. Çıkmadan önce yapılacak islerimiz var. Kullanıcı metni düzenlerken çıkmak isterse ne yapacagız?Öncelikle, maobil cihazın “Geri” tusuna basarak programdan çıkması engellenmeli ve çıkıs kontrollü bir sekilde ya-pılmalıdır. “Geri” tusuna basarak çıkmayı engellemek için programın basında bunu yapmak gerekiyor, yani dahauygulamayı baslatmadan önce. Geri tusu ile çıkısı engellemek için main.py programının ikinci ve üçüncü satırınaasagıdaki kodları yazabilirsiniz:

from kivy.config import ConfigConfig.set('kivy', 'exit_on_escape', 'False')

aslında Config modülü daha fazla is yapabilmektedir. Burada sadece geri tusu ile çıkmayı engellemek için kullandık,bunu exit_on_escape parametresini False yaparak gerçeklestirmis olduk. Windows ya da Linux’da pencere kapatmadügmesi ile hala programdan çıkılıyor olmalı, bunu dikkate almayın çünkü nasıl olsa programımız mobil cihazlardaçalısacak. Geri tusu ile çıkmayı engelledik te, kullanıcı nasıl çıkacak? Isterseniz ana penceremizin sag alt kösesineküçük bir dügme koyalım ve bu dügmeye tıklandıgında çıkısı gerçeklestirelim. Böylelikle çıkmak isteyen kullanıcıbu tusa basacak ve bir islev çagrılacaktır. Bu islevde istedigimizi kontrol edebiliriz. Çıkıs dügmesini eklemek içinmetinduzenleyici.kv dosyasının (Liste 7.2) ana pencere düzenini olusturan metinDuzenleyici formununaltındaki dügmeleri olusturan BoxLayout altına asagıdaki gibi bir dügme ekleyelim:

Button:id: cik_dugmesisize_hint_x: .15

46 Bölüm 7. Metin Düzenleyici

Page 51: Kivy Mobil Programlama - Read the Docs4 Kivy Dili: kv (kv lang) 15 ... Kivy Mobil Programlama, Sürüm 0.2 ... all users” seçili iken “Next” dügmesine tıkladı˘ gınızda

Kivy Mobil Programlama, Sürüm 0.2

background_color: (0, 1, 0, 1)on_press: app.cik()

Dikkat etmisseniz, oldukça küçük bir dügme (%15 boyutunda) ve arka plan rengi yesil olarak görünecek. Bir düg-menin arka plan rengi ni background_color özelligi ile ayarlayabiliyoruz. Bu özellik, diger Kivy renk tanımlarında dakullanılabilecegi gibi, bir tüp (isterseniz bir liste) alır. Bu tüpün 4 elemanı olacaktır. Bu tüp ile rengi söyle belirliyoruz:

(R, G, B, T)

Buradaki harfleri anlamları söyledir:

R: Kırmızı, G: Yesil, B:Mavi

Renk oranlarını belirtmektedir. degerleri 0 ile 1 arasındadır. Bildigimiz standart RGB ile aynı ancak 1 sayısı 255’e kar-sılık gelmektedir. En sondaki T Saydamlıgı belirtmektedir. Bu degere 1 girerseniz tam katı (kesif, opak), 0 girerseniztam saydam olur.

Tekrar dönelim dügmemize, akrka plan rengini neden yesil yaptık? Çünkü yesil doga ve orman rengi degil mi? :-)Elbette bunun için degil, dügme yesil oldugunda çıkıs serbest olacak, kırmızı oldugunda metin degistirilmis fakatkaydedilmemis olacak. O halde programımız içerisinde

self.metin_degisti=False

satırının oldugu her yerde asagıdaki satırı ekleyerek dügmeinin yesil renkli olmasını saglayacagız:

self.root.ids.cik_dugmesi.background_color = [0, 1, 0, 1]

Peki ne zaman kırmızı yapacagız? self.metin_degisti degiskeninin degerinin True oldugu yerlerde. Bunu daprogramımız içerisindeki

self.metin_degisti=True

satırının oldugu her yerde asagıdaki satırı da eklemeliyiz:

self.root.ids.cik_dugmesi.background_color = [1, 0, 0, 1]

Bu satırları yazmayı ben basarabildim, eminim (aslında Mustafa’yım da sözün gelisi) sizde yapabileceksiniz. Çıkdügmesinin yesile dönmesi gereken bir yer daha kaldı: yeniDosyaAc() islevi. Bu islevin en sonuna da asagıdaki satırıeklemeliyiz:

self.root.ids.cik_dugmesi.background_color = [0, 1, 0, 1]

Simdi programınızı çalıstırın ve dügmenin rengini takip edi. Program açılısta yesil renki çık dügmesi ile baslayacak.Ne zaman metin yazarsanız, renk kırmızıya dönecek. Metni kaydettiginizde tekrar yesile dönecek. Ancak henüz çıkdügmesi ise yaramıyor çünkü dügmeye tıklandıgında çagrılacak olan app.cik() islevini yamadık. Önce bu dügme-nin nasıl davranacagını düsleyelim. Bir defa metin degismis ise, programdan çıkmadan önce kaydedilip kaydedilme-yecegini sormalı. O zaman bir tane form olusturmalıyız ve bunu sormalıyız. metinduzenleyici.kv dosyasınaasagıdaki gibi bir form ekleyelim:

Liste 7.7: cikmadanOnceForm

1 <cikmadanOnceForm>:2 title: 'Mevcut Dosya Kaydedilmedi'3 size_hint: (.8, .8)4 BoxLayout:5 orientation: 'vertical'6

7 Label:

7.6. Çıkmadan Önce 47

Page 52: Kivy Mobil Programlama - Read the Docs4 Kivy Dili: kv (kv lang) 15 ... Kivy Mobil Programlama, Sürüm 0.2 ... all users” seçili iken “Next” dügmesine tıkladı˘ gınızda

Kivy Mobil Programlama, Sürüm 0.2

8 size_hint_y: 909 text: "Çalıstıgınız dosya kaydedilmedi. Çıkmak istediginizden emin

→˓misiniz?"10

11 BoxLayout:12 size_hint_y: 1013 Button:14 text: "Vazgeç"15 on_press: root.dismiss()16 Button:17 text: "Yinede Çık"18 on_press: app.stop()

Bu form’da bilmedigiömiz tek sey stop() islevidir. Bu islev uygulamadan çıkma islemini gerçeklestirir. Bu formu kul-lanacak sınıfımızı da class metinDuzenleyici(App) satırından önce asagıdaki kodları ekleyerek yazabiliriz:

class cikmadanOnceForm(Popup):pass

Son olarak cik() islevini yazalım. build()‘den hemen önce asagıdaki satırları yazalım:

def cik(self):if self.metin_degisti:

kaydedilmedi_form = cikmadanOnceForm()kaydedilmedi_form.open()

else:self.stop()

Programımız artık temel ihtiyaçları karsılayacak düzeye geldi. Peki bitti mi? Haaayııır. Neler kaldı? Hayal etmeninsınırı yok. Örnegin son açılan dosyaların listesi, program açıldıgında en çalısılan dosyanın otomatik açılması, kelimebulma ve degistirme ... Baska ? Bir de kahve yapsın, yemek istemiyoruz :-)

Anlattıklarımızı takip edemediyseniz, yada ben yaptıklarımı gözden kaçırıp eksik yazmıssam, bu bölümde anlattıkla-rımı yaptıgım dosyaları su adreslerden alabilirsiniz:

main.py: https://github.com/mbaser/kivy-tr/blob/master/docs/programlar/metinDuzenleyici/6/main.py

metinduzenleyici.kv: https://github.com/mbaser/kivy-tr/blob/master/docs/programlar/metinDuzenleyici/6/metinduzenleyici.kv

48 Bölüm 7. Metin Düzenleyici

Page 53: Kivy Mobil Programlama - Read the Docs4 Kivy Dili: kv (kv lang) 15 ... Kivy Mobil Programlama, Sürüm 0.2 ... all users” seçili iken “Next” dügmesine tıkladı˘ gınızda

BÖLÜM 8

Paketleme

Bu bölümde hazırlanan Kivy programının Android paketi haline getirilmesi anlatılacaktır.

8.1 Buildozer Kurulumu

Kivy programlarını paketlemenin en kolay yolu Buildozer kullanmaktır. Ne yazıkki Buildozer simdilik sadece Linux’taçalısmaktadır. Windows kullanıcıları için VirtualBox üzerinde Sanal Linux Makina disk görüntüsü hazırlanmıstır.Windows kullanıcıları belkide çogu Linux kullanıcıları Sanal Linux Makina bölümünde anlatılanları yapabilirler.

Burada sadece Debian Jessie’de (8.3) nasıl kurulacagını anlatacagız. Sisteminizde git kurulu degilse:

# apt-get install git

Yazılım havuzundan indirelim:

# git clone https://github.com/kivy/buildozer.git

Kurulumu gerçeklestirelim:

# cd buildozer# python setup.py install

Eger sisteminizde eksik paket var ise, size hangilerinin eksik oldugu bildirilecektir. Bu kurulum yeni kurulmus DebianJessie’de (8.3) de denenmistir. Ileriki zamanlarda buildozer debian paketi çıkarsa daha kolay kurulum gerçeklestirile-bilir.

Muhtemelen sisteminizde zlib1g-dev ve Cython kurulu olmayacak:

# apt-get install zlib1g-dev# apt-get install cython

Henüz Java derleyicisini kurmamıs iseniz:

49

Page 54: Kivy Mobil Programlama - Read the Docs4 Kivy Dili: kv (kv lang) 15 ... Kivy Mobil Programlama, Sürüm 0.2 ... all users” seçili iken “Next” dügmesine tıkladı˘ gınızda

Kivy Mobil Programlama, Sürüm 0.2

# apt-get install gcj-jdk

Buildozer’in paketleyebilmesi için 32 bit kütüphanelere ihtiyacı olacak. Su sekilde kurabilirsiniz:

# dpkg --add-architecture i386# apt-get update# apt-get install build-essential ccache lib32z1 libncurses5:i386 libstdc++6:i386→˓openjdk-7-jdk unzip zlib1g:i386

Tüm bu anlattıklarımı, VirtualBox üzerinde bir sanal makinada yaptım ve disk görüntüsünü

kullanımınız için asagıdaki adrese koydum:

https://docs.google.com/uc?export=download&confirm=Ser1&id=0B3-o4L3R6zHvOE9OdDBCUmhLZ0E

Sizin tek yapmanız gereken yapmanız gereken Sanal Linux Makina‘de anlatılan VirtualBox’u kurmak.

8.2 Paket Derleme

Paket haline getirmek için önce baslatalım:

$ buildozer init

Daha sonra buildozer.spec dosyasını düzenleyelim. Ben sadece asagıdaki degisiklikleri yaptım:

# (str) Title of your applicationtitle = Kivy Metin Duzenleyici

# (str) Package namepackage.name = kiviymetinduzenleyici

Simdi de sıra paketlemeye geldi:

$ buildozer android release

Su sekilde baslaması gerekiyor:

# Check configuration tokens# Ensure build layout# Check configuration tokens# Preparing build# Check requirements for android# Install platform....

Ilk kez paketleme yapıyorsanız, ANT, SDK, NDK indirilecektir. Lütfen sabırlı olun. Daha sonra paketleme islemiyapılacaktır. Benim sanal makinamda bu islem 10 dakikadan fazla sürmektedir. Su sekilde sonlanması gerekir:

# Android packages installation done.# Check application requirements# Check garden requirements# Compile platform# Distribution compiled.# Build the application #1# Package the application# Android packaging done!# APK KivyMetinDuzenleyici-0.1-release-unsigned.apk available in the bin directory

50 Bölüm 8. Paketleme

Page 55: Kivy Mobil Programlama - Read the Docs4 Kivy Dili: kv (kv lang) 15 ... Kivy Mobil Programlama, Sürüm 0.2 ... all users” seçili iken “Next” dügmesine tıkladı˘ gınızda

Kivy Mobil Programlama, Sürüm 0.2

Derlenen dosya, derlemeyi baslattıgınız klasörün içerisinde olusturulan bin klasörüne kaydedilmistir. Bu dosyayıAndroid cihaza kurmadan önce imzalamanız gerekmektedir.

8.3 Imzalama

Paketinizi kurmadan önce imzalamanız gerekir. Bunun en kolay yolu apk-signer kullanmaktdır. Programı indirdiktensonra zip paketini açın çalıstırın. Tarafımdan hazırlanan Sanal Linux Makina kullanıyorsanız, masaüstünde apk-signersimgesi üzerine tıklayın.

8.3.1 Anahtar Olusturma

Önce anahtar olusturacagız (Sanal Linux Makina kullananlar için kivy ev klasöründe bir tane anahtar mevcut). Progra-mınız çalıstıgında Key Generator sekmesinde olacaktır. Bu sekmede iken ilk yapacagınız anhtarınızı kaydedeceginizdosyayı belirlemek. Bu amaçla [ Save as... ] dügmesine tıklayın. Anahtarınızı kaydedeceginiz klasörü seçin (bizdekiörnekte /home/kivy) ve dosya adını yazın (biz benim yazdık). Yaptıklarımız Sekil 8.1 görünmektedir.

Sekil 8.1: Anahtar Dosyası

Daha sonra gerekli bilgileri doldurun. Password ve Confirm alanlarına aynı parolayı girin (en az 8 karakter). Bizim ör-negimizde kivy123 girdik. Bir Alias belirleyin, biz Kivy yaptık. Alias’ınız için yine parola (Alias password ve Confirmalanlarına) girin. Biz yine kivy123 girdik. Bu parolaları unutmayın, çünkü bundan sonra imzalayacagınız her pakettekullanacaksınız. Diger alanları istediginiz gibi doldurun. Sekil 8.1‘de olusturdugumuz anahtar için bilgilerin girilmishali görünmektedir.

8.3. Imzalama 51

Page 56: Kivy Mobil Programlama - Read the Docs4 Kivy Dili: kv (kv lang) 15 ... Kivy Mobil Programlama, Sürüm 0.2 ... all users” seçili iken “Next” dügmesine tıkladı˘ gınızda

Kivy Mobil Programlama, Sürüm 0.2

Sekil 8.2: Anahtar Olusturma

Generete Keyfile dügmesine tıklayarak anahtarınızı olusturun.

8.3.2 Imzalama

Anahtarınızı (aslına imzanız) olusturduktan hemen sonra paketinizi imzalayabilirsiniz. Bunun için Signer sekmesinegeçin. Önce [ Load Keyfile... ] dügmesine tıklayarak, olusturdugunuz anahtarı seçin. Eger olustruruken yukarıdakigibi benim yazmıssanız, ev dizininizde benim.keystroke dosyasını seçin. Bu imzanın parolasını Password alanına ya-zın. Bir Alias seçin (yukarıda Kivy yazdık) ve bunun parolasını Alias password alanına girin. [ Load target file...] dügmesine tıklayın. Açılan pencerede imzalamak istediginiz paketi seçin, biz Kivy Metin Düzenleyici’yi derlemis-tik onu seçiyoruz (MetinDuzenleyici/bin/ KivyMetinDuzenleyici-0.1-release-unsigned.apk). Yaptıklarımız Sekil 8.3‘degörünmektedir.

Son olarak Sign dügmesine tıklayın. Simdi MetinDuzenleyici/bin/KivyMetinDuzenleyici-0.1-release-SIGNED_UNALIGNED.apk dosyasını bir Android cihaza kurabilirsiniz.

8.4 Sanal Linux Makina

Windows kullanıcıları için Linux’u ve diger paketleri kurmadan (epeyce zahmetli bir is), programlarını apk halinegetirebilecekleri bir sanal makina disk görüntüsü hazırlanmıs https://docs.google.com/uc?export=download&confirm=Ser1&id=0B3-o4L3R6zHvOE9OdDBCUmhLZ0E adresine konulmustur. Bu dosyayı indirin ve bir arsiv programı ile(örnegin winrar) masaüstüne açın.

Sanal makine disk görüntüsü Oracle VirtualBox 5.0.16 r105871 sürümü ile hazırlanmıstır. Kullanıcılar mutlaka busürümü indirmelidir. Diger sürümlerde windows-linux baglantısı saglanamayabilir ve ana makinanızın dosyalarınaerisiminiz olamayabilir.

52 Bölüm 8. Paketleme

Page 57: Kivy Mobil Programlama - Read the Docs4 Kivy Dili: kv (kv lang) 15 ... Kivy Mobil Programlama, Sürüm 0.2 ... all users” seçili iken “Next” dügmesine tıkladı˘ gınızda

Kivy Mobil Programlama, Sürüm 0.2

Sekil 8.3: APK Paketini imzalama

8.4.1 VirtualBox kurulumu

https://www.virtualbox.org/wiki/Download_Old_Builds_5_0 adresinden 5.016 sürümünü indirin ve inen dosya üze-rine çift tıklayın. Birkaç “Next” dügmesine tıkladıktan sonra “Install” dügmesine tıklayın. Size uyarı “Bu aygıt yazı-lımını ....” uyarısını verdiginde “Yükle” dügmesine tıklayın.

8.4.2 Sanal Makina Olusturma

Vitrualbox açıldıgında yeni bir sanal Makine olusturmak için sol üst kösedeki “Yeni” dügmesine tıklayın. Açılanpencerede “Adı” alanına istediginiz bir isim yazın, ben kivy yazmayı tercih ettim. Türü “Linux”, Sürüm “Debian(32-bit)” seçin (Sekil 8.4‘de)

“Ileri” dügmesine tıkladıgınzda sanal makine için ayıracagınız bellegi seçmeniz gerekmektedir. Her ne kadar 768MBönerilse de, 1024MB’den daha fazla bir bellek ayırmaya çalısın. Ben genelde 1536MB (1.5GB) ayrımayı tercih edi-yorum (Sekil 8.5‘de):

“Ileri” dügmesine tıkladıgınızda sanal makinanın kullanacagı disk görüntüsünü belirleyeceginiz pencere gelecektir.

Burada “Var olan sanal bir sdabit disk dosyası kullan” seçenegini seçip, simgesine tıklayın ve daha önce indiripaçtıgınız deb-i386.vdi dosyasını seçin (Sekil 8.6‘de):

“Olustur” dügmesine tıkladıgınızda sanal makinanız hazır olacaktır.

8.4.3 Paylasım Açma

Makinanızı baslatmadan önce, Windows kolasörlerinize erisimi saglayacak olan paylasımıda yapmalısınız. Bu payla-sım sayesinde Windows makinanızda yazmıs oldugunuz Kivy programlarına sanal Makine içerisinden erisebilecek ve

8.4. Sanal Linux Makina 53

Page 58: Kivy Mobil Programlama - Read the Docs4 Kivy Dili: kv (kv lang) 15 ... Kivy Mobil Programlama, Sürüm 0.2 ... all users” seçili iken “Next” dügmesine tıkladı˘ gınızda

Kivy Mobil Programlama, Sürüm 0.2

Sekil 8.4: Makina mimarisi seçimi

Sekil 8.5: Sanal makinenin bellegini belirleme

54 Bölüm 8. Paketleme

Page 59: Kivy Mobil Programlama - Read the Docs4 Kivy Dili: kv (kv lang) 15 ... Kivy Mobil Programlama, Sürüm 0.2 ... all users” seçili iken “Next” dügmesine tıkladı˘ gınızda

Kivy Mobil Programlama, Sürüm 0.2

Sekil 8.6: Sanal makinenin diskini belirleme

derleme islemini yapabileceksiniz. Bunun için “Ayarlar” dügmesine tıklayın. Açılan pencerenin sol panelinden “Pay-

lasılan Klasörler”i seçin. Sag paneldeki simgesine tıklayarak yeni bir paylasım ekleme penceresi açın. Bu pen-cerede Klasör Yolu’ na sanal Makine ile paylasmak istediginiz klasörü seçin. Ben masaüstümdeki kivy klasöürünüseçtim. Klasör Adı’nı “windows” olarak degistirin. Eger degistirmez iseniz, sanal makinada paylasımlar /media/sf_paylasimadi olarak baglanacaktır. Hazırladıgım disk görüntüsünde “windows” paylasımını kivy kullanıcısınınev dizinine köprüledigimden Klasör Adını’nı “windows” olarak degistirmenizde fayda var. “Tamam” dügmesine tık-lamadan önce “Otomatik-bagla” seçenegini isaretlemeyi unutmayın (Sekil 8.7).

Sanal makinayı baslatmak için sola panledeki Makine ismi üzerine çift tıklayın. Makinanız bir süre sonra açılacaktır.Açılan makinada kivy kullanıcısı oturum açmıs durumundadır. root ve kivy kullanıcılarının parolaları kivy123 olarakbelirlenmistir (masaüstündeki OKUBENI.txt dosyasında mevcut). Açılan sanal makineyi Sekil 8.8 ‘de görüyorsunuz.söyle

Örnek bir derleme yapalım. Bunun için ben metin düzenleyiciyi derlemek istiyorum. Bu nedenle asagıdaki dosyalarıWindows makinamın masaüstündeki kivy klasörüne kaydettim (paylastıgım klasör).

https://github.com/mbaser/kivy-tr/blob/master/docs/programlar/metinDuzenleyici/6/main.py

https://github.com/mbaser/kivy-tr/blob/master/docs/programlar/metinDuzenleyici/6/metinduzenleyici.kv

Sanal makinede “Uçbirim Öykünücüsü” üzerine tıklayın. Bu size komut satırını açacaktır (su Linux’çuların meshursiyah ekranı). Windows makinadan paylasılan klasör sanal makinadaki kivy kullanıcısının ev dizinindeki windowsklasörüne köprilendiginden, komut satırında asagıdaki komutu isletin Önce kivy kullanıcısının ev dizininde denemeisimli bir klasör olusturalım ve derleyecegimiz dosyaları buraya kopyalayalım (bastaki dolar $ isaretleri konulamya-caktır):

$ mkdir deneme$ cp windows/main.py deneme

8.4. Sanal Linux Makina 55

Page 60: Kivy Mobil Programlama - Read the Docs4 Kivy Dili: kv (kv lang) 15 ... Kivy Mobil Programlama, Sürüm 0.2 ... all users” seçili iken “Next” dügmesine tıkladı˘ gınızda

Kivy Mobil Programlama, Sürüm 0.2

Sekil 8.7: Sanal makine için paylasım açma

56 Bölüm 8. Paketleme

Page 61: Kivy Mobil Programlama - Read the Docs4 Kivy Dili: kv (kv lang) 15 ... Kivy Mobil Programlama, Sürüm 0.2 ... all users” seçili iken “Next” dügmesine tıkladı˘ gınızda

Kivy Mobil Programlama, Sürüm 0.2

Sekil 8.8: Linux Sanal Makine

8.4. Sanal Linux Makina 57

Page 62: Kivy Mobil Programlama - Read the Docs4 Kivy Dili: kv (kv lang) 15 ... Kivy Mobil Programlama, Sürüm 0.2 ... all users” seçili iken “Next” dügmesine tıkladı˘ gınızda

Kivy Mobil Programlama, Sürüm 0.2

$ cp windows/metinduzenleyici.kv deneme

Bu klasöre geçis yapalım ve buildozer’i baslatalım:

$ cd deneme/$ buildozer init

buildozer.spec dosyasını düzenlemek için komut satırında asagıdaki komutu isletin:

$ mcedit buildozer.spec

Deneme derlemesi için sadece asagıdaki degisiklikleri yapın

# (str) Title of your applicationtitle = Kivy Metin Duzenleyici

# (str) Package namepackage.name = kiviymetinduzenleyici

kaydetmek için klavyeden F2 tusuna çıkmak için F10 tusuna basın. Derlemek için komut satırından asagıdaki komutuçalıstırın.

$ buildozer android release

su sekilde baslaması gerekiyor:

# Check configuration tokens# Ensure build layout# Check configuration tokens# Preparing build# Check requirements for android# Install platform....

Buradan sonrasını Paket Derleme ‘den takip edebilirsiniz. Derlenen dosya, derlemeyi baslattıgınız klasörün içerisindeolusturulan bin klasörüne kaydedilmistir. Bizi,m örnegimizde kivy kullanıcısının ev klasöründe bulunan deneme/bin klasöründe olacaktır.

Bu dosyayı Android cihaza kurmadan önce imzalamanız gerekmektedir. Imzaladıktan sonra sanal mekinenizin masa-üstündeki “Ev” simgesine tıklayarak dosya yöneticisini çalıstırabilir ve imzalanmıs apk dosyasını Windows makine-nizden erismek üzere ev klasörünüzdeki windows klasörüne kopyalayabilirsiniz.

58 Bölüm 8. Paketleme

Page 63: Kivy Mobil Programlama - Read the Docs4 Kivy Dili: kv (kv lang) 15 ... Kivy Mobil Programlama, Sürüm 0.2 ... all users” seçili iken “Next” dügmesine tıkladı˘ gınızda

BÖLÜM 9

Atlıkarınca ve Resim Gösterici

Atlı karınca dememizin nedeni “carousel” kelimesi Ingilizce’de “atlıkarınca” anlamını tasıması, elbette bir de at ya-rıslarındaki gösteri turnuvasına denmekte, ancak “carousel” isminin neye dayanarak verildigini bilmiyorum (meraketmiyor da degilim, yoksa su parklarda gördügümz askıda dönen salıncaklardan mı geliyor acabaga). Bu “Carousel”denen sey nedir? Cep telefonunuzu kullanırken, ekranı saga sola (ya da üste alta) parmaklarınızın ucu ile kaydırıyor-sunuz ya, iste o. Bu bölümde Corusel (atlıkarınca) kullanarak bir resim gösterici yapmayı planlıyoruz. Normalde birresim göstericisini atlıkarınca ile yapmak ne kadar mantıklı bilemiyorum. Çünkü tüm resimleri basta atlıkarıncayayüklüyorsunuz. Bu da sanırım bellek kullanımını artırır. Her neyse biz burada bu atlıkarıncayı nasıl kullanacagımızıögrenecegiz.

9.1 Atlıkarınca (Carousel)

Atlıkarınca, bir çesit düzen gibi düsünülebilir. Bu düzen kendi çerisinde çesitli sekemeleri bulunan ve her sekme-nin kendi düzeni bulunan bir yapıdır. Sekmeler bir pencerede bulunmaz, kaydırılarak ulasılırlar. Burada atlıkarıncasekmelerine sadece etiket (sonraki kesimde resim) koyacagız, ancak herhengi bir düzen de koyabilirsiniz.

Önce atlıkarıncanın nasıl çalıstıgını ögrenelim. Atlıkarınca Carousel nesnesi ile olusturulur. Istenilen bir düzen(tek bir etiket, tek bir resim ya da diger düzenler) bu nesneye add_widget özelligi ile eklenir. Liste 9.1‘deki gibimain.py dosyasını yazalım.

Liste 9.1: main.py

1 # -*- coding: utf-8 -*-2

3 from kivy.app import App4 from kivy.uix.carousel import Carousel5 from kivy.uix.label import Label6

7 class atliKarinca(App):8

9 def build(self):10 karinca = Carousel()11 for i in range(5):

59

Page 64: Kivy Mobil Programlama - Read the Docs4 Kivy Dili: kv (kv lang) 15 ... Kivy Mobil Programlama, Sürüm 0.2 ... all users” seçili iken “Next” dügmesine tıkladı˘ gınızda

Kivy Mobil Programlama, Sürüm 0.2

12 karinca.add_widget(Label(text="Karınca Sayfası: %d" %i))13

14 return karinca15

16 atliKarinca().run()

Bu programı biraz açıklayalım: 10. satırda bir atlıkarınca nesnesi olusturuluyor. Daha sonra bu karıncaya 5 adet etiketekleniyor. Her etiketin üzerinde “Karınca Sayfası: 0”, “Karınca Sayfası: 1” ... yazmaktadır. Programı çalıstırıp fareile sayfayı sola dogru itip bırakın. Bu size sonraki sayfayı görüntüleyecektir. Mobil cihazlarda, sayfayı parmagınız ilesola dogru itmeniz yeterlidir. Atlıkarıncanın yönü ön tanımlı olarak sola dogrudur. Isterseniz bunu direction özelligi(parametresi) ile degistirebilirsiniz. Bu parametrenin (ya da özelligin) alabilecegi degerler sunlardır: right, left, top,bottom. Sanırım bunları açıklamaya gerek yok. Programın çalısmıs halini Sekil 9.1‘de görüyorsunuz.

Sekil 9.1: Atlıkarınca

9.2 Resim Gösterici

Atlıkarıncaya etiket yerine, resim grafik parçacıgını eklersek, metin yerine resimleri göstermis olur.

9.2.1 Bir Klasördeki Resimler

Atlıkarıncayı basit olarak, programın bulundugu dizindeki resimleri gösterecek sekilde kullanmaya çalısalım. Dahasonra programımızı gelistirecegimizden kv dilini kullanarak hazırlayalım. Öncelikle resimgosterici.kv dosya-mızı Liste 9.2‘deki gibi yazalım.

60 Bölüm 9. Atlıkarınca ve Resim Gösterici

Page 65: Kivy Mobil Programlama - Read the Docs4 Kivy Dili: kv (kv lang) 15 ... Kivy Mobil Programlama, Sürüm 0.2 ... all users” seçili iken “Next” dügmesine tıkladı˘ gınızda

Kivy Mobil Programlama, Sürüm 0.2

Liste 9.2: resimgosterici.kv

1 <resimGosterici>:2 BoxLayout:3 orientation: "vertical"4 Carousel:5 size_hint_y: 906 id: karinca7

Buarada anadüzenimizi BoxLayout yaptık çünkü ilerde dügmeler yerlestirecegiz. Onun dısında bilmediginiz bir kodbulunmuyor. Atlıkarıncayı 4. satırdaki Carousel ile olısturduk. Bu nesneye ulasmak için id’sini karinca yaptık.Bu kv dosyasını kullanıp, programın çalıstıgı klasördeki png resimlerini gösterecek main.py programını da Liste9.3‘deki gibi yazabiliriz.

Liste 9.3: main.py

1 # -*- coding: utf-8 -*-2

3 import os4 from kivy.app import App5 from kivy.uix.image import Image6

7 class resimGosterici(App):8

9 def build(self):10 self.son_patika=os.getcwd()11 for dosya in os.listdir(self.son_patika):12 if os.path.splitext(dosya)[1]=='.png':13 resim=Image(source=dosya)14 self.root.ids.karinca.add_widget(resim)15

16 resimGosterici().run()

Bu programda os.listdir() ile bulundugumuz klasördeki (os.getcwd() ile alınıyor) dosylara üzerinde biriterasyon yapılıyor (11. satır). Iterasyon içerisinde os.path.splitext() ile dosyaların (dosya_adı, uzantisi) sek-linde ayrılıyor ve uzantısı .png olan dosyalardan bir resim nesnesi olusturuluyor. Resim nesnesi Image sınıfı ile olustu-rulur. Bu sınıfa source paramteresi ile olusturulacak resmin tam dosya adı (yada programın çalıstıgı klasördeki dosyaadı) verilir. Olusturulan resim nesnesi atlıkarıncanın add_widget özelligi ile ekleniyor. Ben programın çalıstıgıklasöre Kivy, Android ve Python logolarını koydum (umarım telif haklarını ihlal etmemisimdir). Programı çalıstırıpresmi sürüklerken ekran görüntüsünü asagıdaki (Sekil 9.2) gibi aldım.

Bir klasördeki resimleri dosyaların uzantılarına bakarak belirlemek deyim yerinde ise amele isi (burada ameleleriküçümsemek gibi bir niyetimin olmadıgını belirteyim), çünkü onlarda resim formatı var. Bunun yerine bir dosyanınresim olup olmadıgını, Python’un imghdr modülünü kullanarak anlayabiliriz. Bu modülün what özelligi resimdosyasının tipini döndürür. Dosya resim degil ise hiçbirsey döndürmez. O Halde programımızı Liste 9.4‘deki gibigüncelleyebiliriz.

Liste 9.4: main.py

1 # -*- coding: utf-8 -*-2

3 import os, imghdr4 from kivy.app import App5 from kivy.uix.image import Image6

7 class resimGosterici(App):

9.2. Resim Gösterici 61

Page 66: Kivy Mobil Programlama - Read the Docs4 Kivy Dili: kv (kv lang) 15 ... Kivy Mobil Programlama, Sürüm 0.2 ... all users” seçili iken “Next” dügmesine tıkladı˘ gınızda

Kivy Mobil Programlama, Sürüm 0.2

Sekil 9.2: Basit Resim Gösterici (kaydırırken)

8

9 def build(self):10 self.son_patika=os.getcwd()11 for dosya in os.listdir(self.son_patika):12 if imghdr.what(dosya):13 resim=Image(source=dosya)14 self.root.ids.karinca.add_widget(resim)15

16 resimGosterici().run()

Programın 2. satırında imghdr modülünü içerdigimize dikkat edin.

Atlıkarıncaya resimleri build() altında eklemek mantıklı olmayacaktır. Çünkü ilerde çesitli yollarla resim ekleye-cegiz her seferinde aynı islemleri yapmamız gerekecek. Bunun yerine bir islev yazalım ve resimleri orada ekleyelim.Islevimiz kendisine bir liste halinde gelen dosyaları atlıkarıncaya eklesin. Eger resimler programın çalıstıgı dizin degilde (muhtemel olmayacak) baska bir yerde ise o zaman resimlerin tam patikasını vermek gerekecek. Bunu Liste 9.5‘’de17. satırda kolayca yaptık.

Liste 9.5: main.py

1 # -*- coding: utf-8 -*-2

3 import os, imghdr4 from kivy.app import App5 from kivy.uix.image import Image6

7 class resimGosterici(App):8

9 def resimleriEkle(self, dosyalar):10 self.root.ids.karinca.clear_widgets()11 if os.path.isfile(dosya):

62 Bölüm 9. Atlıkarınca ve Resim Gösterici

Page 67: Kivy Mobil Programlama - Read the Docs4 Kivy Dili: kv (kv lang) 15 ... Kivy Mobil Programlama, Sürüm 0.2 ... all users” seçili iken “Next” dügmesine tıkladı˘ gınızda

Kivy Mobil Programlama, Sürüm 0.2

12 for dosya in dosyalar:13 if imghdr.what(dosya):14 resim=Image(source=dosya)15 self.root.ids.karinca.add_widget(resim)16

17 def build(self):18 self.son_patika=os.getcwd()19 dosyalar=[ os.path.join(self.son_patika, x) for x in os.listdir(self.son_

→˓patika) ]20 self.resimleriEkle(dosyalar)21

22 resimGosterici().run()

Burada resimleriEkle() islevinde kullandıgımız atlıkarıncanın clear_widgets özelligi, daha önce eklenmis tümnesneleri (burada resimler) temizlemek içindir. Bu satırı yazmadıgımız taktirde önceki resimler de görünecektir. Ay-rıca, os.path.isfile(dosya) kontrolü ile, seçilen klasörde bir baska lat klasör var ise, buna ait resim tipikontrolünün yapılmamasını sagladık.

Burada 19. satırı su sekilde de yazabilirdiniz:

dosyalar=[]for x in os.listdir(self.son_patika):

dosyalar.append(os.path.join(self.son_patika, x))

Önceki yazdıgımız daha kısa olmalı.

9.2.2 Klasörü Seçme

Resimler çogu zaman, önceden belirlenen bir klasör yerine, kullanıcının programı çalıstırdıktan sonra seçecegi birklasörde bulunacaktır. Bunu daha önce Metin Düzenleyici ‘de yapmıstık. Bunun için FileChooserListView‘ i kulla-nabiliriz. Fakat burada bir degisiklik yapalım ve index:‘FileChooserIconView kullanalım. Ikisinin de kullanımı ben-zer, sadece görüntüleri farklı. FileChooserIconView dosya ve klasörleri görüntülerken liste, degil simgelerlegöstermektedir. Bu grafik parçacıgını kv dosyasındaki bir form içerisinde kullanacagız. Ilk olarak Liste 9.2 dakiresimgosterici.kv dosyasına asagıdaki kodları ekleyin:

Liste 9.6: acForm

1 <acForm>:2 title: "Klasör/Dosya Aç"3 size_hint: (.9, .9)4

5 BoxLayout:6 orientation: 'vertical'7

8 FileChooserIconView:9 size_hint_y: 90

10 id: dosya_secim11 filters: ['*.*']12 path: app.son_patika13 multiselect: True14

15 BoxLayout:16 size_hint_y: 1017 Button:18 text: "Seçilenleri Aç"19 on_press: app.secilenResimler(root); root.dismiss()20 Button:

9.2. Resim Gösterici 63

Page 68: Kivy Mobil Programlama - Read the Docs4 Kivy Dili: kv (kv lang) 15 ... Kivy Mobil Programlama, Sürüm 0.2 ... all users” seçili iken “Next” dügmesine tıkladı˘ gınızda

Kivy Mobil Programlama, Sürüm 0.2

21 text: "Tüm Resimler"22 on_press: app.tumResimler(root); root.dismiss()

Burada farklı olarak multiselect özelliginin degerini True yaptıgımızı görüyorsunuz. Bu, kullanıcının birden fazladosyayı seçebilmesine olanak tanıyacaktır. Bu kv formunu kullanacak sınıfı tanımlamak gerekiyor. Bunu classresimGosterici(App) satırından önce asagıdaki kodları ekleyerek yapabiliriz:

class acForm(Popup):pass

main.py programında bu sınıfı tanımlamadan önce asagıdaki gibi Popup‘ı içermeyi unutmayın.

from kivy.uix.popup import Popup

Yeni formumuzu açabilmek için ana pencerede bir dügme koymalıyız, ki bu formu açsın. Bunu resimgosterici.kv dosyasındaki resimGosterici formunu asagıdaki gibi düzenleyerek yapabiliriz:

<resimGosterici>:BoxLayout:

orientation: "vertical"Carousel:

size_hint_y: 90id: karinca

BoxLayout:size_hint_y: 10Button:

text: "Aç"on_press: app.klasorAc()

Buarada klasorAc() islevi ile acForm‘u açacagız. Ikinci bir BoxLayout eklememizin nedeni ilerde baska düg-meleri de koyacagımızdır. Önce dügmeye tıklandıgında formun açılabilmesi için build() den önce asagıdaki isleviyazalım:

def klasorAc(self):form=acForm()form.open()

Ana penceredeki “Aç” dügmesine tıklandıgında Sekil 9.3‘deki gibi açılacaktır.

Önce tüm resimleri gösterebilmesi için , tumResimler() islevini yazalım. Asagıdaki islevi build() den hemenönce yazın:

def tumResimler(self, kok):self.son_patika=kok.ids.dosya_secim.pathdosyalar=[ os.path.join(self.son_patika, x) for x in os.listdir(self.son_patika) ]self.resimleriEkle(dosyalar)

Sanırım bu islevdeki her satır sizin için anlasılır. Yaptıgımız tek sey son_patika degiskenine,FileChooserIconView nesnesinden dosya_secim.path degerini atamak oldu. Eger bir resmi tüm tuvale ge-nisletmek istiyorsanız, resim nesnesinin allow_stretch özelligini True yapmalısınız. Bunu yaptıgınızda en-boy oranıyine de korunacaktır. En-boy oranının da tuval’e esitlenmesiniz istiyorsanız resim nesnesinin keep_ratio özelliginiFalse yapmanız gerekmektedir. Bunlar için resimleriEkle() islevindeki resim=Image(source=dosya)satırından sonra su satırları ekleyebilirsiniz:

resim.allow_stretch=Trueresim.keep_ratio=False

64 Bölüm 9. Atlıkarınca ve Resim Gösterici

Page 69: Kivy Mobil Programlama - Read the Docs4 Kivy Dili: kv (kv lang) 15 ... Kivy Mobil Programlama, Sürüm 0.2 ... all users” seçili iken “Next” dügmesine tıkladı˘ gınızda

Kivy Mobil Programlama, Sürüm 0.2

Sekil 9.3: Dosya veya Klasör Seçimi

9.2. Resim Gösterici 65

Page 70: Kivy Mobil Programlama - Read the Docs4 Kivy Dili: kv (kv lang) 15 ... Kivy Mobil Programlama, Sürüm 0.2 ... all users” seçili iken “Next” dügmesine tıkladı˘ gınızda

Kivy Mobil Programlama, Sürüm 0.2

Bu satırları ekledigimizde açılan resimler tüm tuval’i kaplayacaktır. Simdide sadece seçilen resimleri göstermek üzeresecilenResimler() islevini yazalım. Asagıdaki islevi build() den hemen önce yazalım:

def secilenResimler(self, kok):self.son_patika=kok.ids.dosya_secim.pathdosyalar=kok.ids.dosya_secim.selectionself.resimleriEkle(dosyalar)

Öncekinden daha kolay oldu, sadece son_patika yı belirlemek ve dosyaları almak oldu. Dikkat edersenin seçilendosyalar ile patikayı birlestirmedik, çünkü FileChooser nesnesi seçilen dosyayı patikası ile birlikte verir.

Programımız burada bitti, ancak kullanıcların istekler sonsuzdur. Bir programı yazmaya baslarken sadece temel ihti-yaçları göz önünde bulundurarak baslarız. Sonra aklımıza gelen eklentileri ya da kullanıcıların uygulanabilir makulisteklerini ekleriz. Söyle bir sey aklımıza gelse “Slay gösterisi”. Gelin simdi bunu yapalım.

9.3 Zamanlayıcı ve Slayt Gösterisi

Slayt gösterisini yapabilmek için, zamanlayıcı ya (timer) ihtiyacımız var. Neden mi? Eger resimler arası geçis zamanınıtime.sleep() ile ayarlarsanız, döngü bitene kadar program ile etkilesim yapılamaz. Bu nedenle zamanlayıcıyaihtiyacımız var. Zamanlayıcıyı program içerisinde çalısan bir saat olarak düsünebilirsiniz. Bu saat her tık atısındabir islevi çagırır ve sizde bu islevde yapılması gerekenleri kodlarsınız. Öncelikle ekranın en altına slayt gösterisinibaslatıp durdurabilecegimiz bir dügme ekleyelim. Bunu kv dosyasındaki <resimGosterici> formunun altındakiBoxLayout düzenine asagıdaki satırları ekleyerek yapabiliriz:

Button:id: slyat_dugmetext: "Slaytı Baslat"on_press: app.slaytGosterisi(root)

Eger hiç resim yüklenmediyse, bu dügmeyi pasiflestirmek gerekir. Kivy’de bir nesneyi pasiflestirmek için disabledözelligine Treu ataması yaparız. Ön tanımlı olarak nesnelerin disabled özelligi False konumundadır. O haldeöncelikle build() islevinin en sonuna asagıdaki satırı ekleyelim:

self.root.ids.slyat_dugme.disabled=True

Böylelikle, program basladıgında atlıkarıncada hiç resim olmayacagından, digme etkin olmayacaktır. Bir de,resimleriEkle() islevinin en altına asagıdaki satırları eklemeliyiz:

if self.root.ids.karinca.slides:self.root.ids.slyat_dugme.disabled=False

else:self.root.ids.slyat_dugme.disabled=True

Nedenini söyle açıklayalım. Herhangi bir dügmeye tıklayarak, atlıkarıncaya resim eklenmisse, self.root.ids.karinca.slides degeri None dan farklı olacaktır ve dügme etkinlesecektir aksi halde dügme pasif olacaktır.

Slayt gösterisi için zamanlayıcıya ihtiyacımız oldugunu söyledik, bunun için kivy modüllerini içerdigimiz satırlarınsonuna su satırı ekleyelim:

from kivy.clock import Clock

<resimGosterici> formuna ekledigimiz id si slyat_dugme olan dügmeye tıklandıgındaslaytGosterisi() islevi çagrılacaktır. Sim bunu build() den hemen önce su sekilde yazalım:

66 Bölüm 9. Atlıkarınca ve Resim Gösterici

Page 71: Kivy Mobil Programlama - Read the Docs4 Kivy Dili: kv (kv lang) 15 ... Kivy Mobil Programlama, Sürüm 0.2 ... all users” seçili iken “Next” dügmesine tıkladı˘ gınızda

Kivy Mobil Programlama, Sürüm 0.2

def slaytGosterisi(self, kok):if kok.ids.slyat_dugme.text=="Slaytı Baslat":

Clock.schedule_interval(self.zamanlayiciIslevi, 1)kok.ids.slyat_dugme.text="Slaytı Durdur"

else:Clock.unschedule(self.zamanlayiciIslevi)kok.ids.slyat_dugme.text="Slaytı Baslat"

Bu isleve baslarken, slayt gösterisi devam ediyor mu etmiyor mu onu kontrol ederek basladık. Bunu slyat_dugmenin üzerindeki metni kullanarak kontrol ettik. Eger dügme metni “Slaytı Baslat” ise, slayt baslamamıstır ve bu bloktaslaytı baslatıyoruz. Slaytı baslatmak için saatin (Clock) tik atıs aralıgını veriyoruz. Bunu Clock nesnesinin sche-dule_interval özelligi ile yaparız. Zamanlayıcı su sekilde baslatılır:

Clock.schedule_interval(islev, atis_zaman_araligi)

Burada islev her tık attıgında çagrılacak islevi ve zaman_araligi tik aralıklarını saniye cinsinden ifade etmektedir.Programımızda her tık atısta zamanlayiciIslevi() çagrılacaktır. Tık aralıkları ise 1 saniye olarak verilmistir.Zamanlayıcı (daha dogrusu slayt gösterisi) basladıktan sonra, slyat_dugme nin üzerindeki metni “Slaytı Durdur”olarak degistiriyoruz. Böylelikle aynı dügme salytı hem baslatmak hem de durdurmak için kullanılıyor.

Zamanlayıcı su sekilde durdurulur:

Clock.unschedule(islev)

Zamanlayıcı ayrı islevleri çagırmak için planlanabilir (schedule edilebilir) ve her seferinde isev ile atis_zaman_araligifarklı olabilir. Planlanmıs bir zamanlayıcıyı durdurmak için unschedule özellegini kullanıyoruz.

Buradan anlasılacagı gibi slayt gösterisini yapacak islevin çagrılmasını durdurmak için (planı bozmak için): Clock.unschedule(self.zamanlayiciIslevi) satırını kullandık ve hemen sonrasında slyat_dugme nin üze-rindeki metni “Slaytı Baslat” yaptık.

Simdide salyat gösterini yapacak olan zamanlayiciIslevi() islevini yazalım. Bu islev zamanlayıcının her tikatısında çagrılacaktır. Her çagrılısta atlı karıncanın bir sonraki slaytını göstermesi gerekir. Atlıkarıncanın sonraki slaytıgöstermesi için load_next isevini kullanırız (önceki için load_previous‘). Zamanlayıcı islevini slaytGosterisi()nden önce asagıdaki gibi yazabiliriz:

def zamanlayiciIslevi(self, za):self.root.ids.karinca.load_next()

Zamanlayıcı islevi çagırırken ilk argüman olarak, iki tik atısltaki zaman aralıgını verir (belki programcının bunu kul-lanmaya ihtiyacı olabilir), bunu islevimizde za olarak aldık.

Slayt gösterisi bittiginde (en son resme gelindiginde), sonraki resim gösterileyemecektir ve sürekli aynı resimde at-lam olacaktır. Eger atlıkarıncanın sonsuz döngüde (sona geldiginde tekrar basa sarma) çalısmasını istiyorsanız loopözelligini True yapmalısınız. Programımızda build() islevinin basına asagıdaki satırı ekleyerek sonsuz döngüyesokmus oluruz:

self.root.ids.karinca.loop=True

Son durumda programımızın penceresi Sekil 9.4‘deki gibi açılacaktır.

Anlattıklarımızı takip edemediyseniz, yada ben yaptıklarımı gözden kaçırıp eksik yazmıssam, bu bölümde anlattıkla-rımı yaptıgım dosyaları su adreslerden alabilirsiniz:

main.py: https://github.com/mbaser/kivy-tr/blob/master/docs/programlar/resimGosterici/5/main.py

metinduzenleyici.kv: https://github.com/mbaser/kivy-tr/blob/master/docs/programlar/resimGosterici/5/resimgosterici.kv

9.3. Zamanlayıcı ve Slayt Gösterisi 67

Page 72: Kivy Mobil Programlama - Read the Docs4 Kivy Dili: kv (kv lang) 15 ... Kivy Mobil Programlama, Sürüm 0.2 ... all users” seçili iken “Next” dügmesine tıkladı˘ gınızda

Kivy Mobil Programlama, Sürüm 0.2

Sekil 9.4: Slayt Gösterici

68 Bölüm 9. Atlıkarınca ve Resim Gösterici

Page 73: Kivy Mobil Programlama - Read the Docs4 Kivy Dili: kv (kv lang) 15 ... Kivy Mobil Programlama, Sürüm 0.2 ... all users” seçili iken “Next” dügmesine tıkladı˘ gınızda

Kivy Mobil Programlama, Sürüm 0.2

9.4 Kronometre Uygulaması

Zamanlayıcı kullanarak bir kronometre yapınız. Kronometrede iki dügme bulunmalıdır: Baslat ve Sıfırla Baslat düg-mesine tıklanınca kronomtere baslayacak ve üzerindeki metin Durdur olacaktır. Sıfırla dügmesine tıklanınca krono-metre sıfırlanacaktır. Kronometre tıklama aralıgı 0.1 saniye (1 salise) olacaktır. Etiketteki metnin büyüklügünü 100piksel yapınız. Bir etiketin yazıtipi büyüklügünü font_size özelligi ile ayarlayabilirsiniz. Kronometre sayaç görüntüsüdak:saniye.salise seklinde olacaktır.

Kronometreniz çalıstıgında Sekil 9.5‘deki gibi bir pencere olacaktır.

Sekil 9.5: Kronometre

Çözüm:

main.py: https://github.com/mbaser/kivy-tr/blob/master/docs/programlar/resimGosterici/kronometre/main.py

kronometre.kv: https://github.com/mbaser/kivy-tr/blob/master/docs/programlar/resimGosterici/kronometre/kronometre.kv

9.4. Kronometre Uygulaması 69

Page 74: Kivy Mobil Programlama - Read the Docs4 Kivy Dili: kv (kv lang) 15 ... Kivy Mobil Programlama, Sürüm 0.2 ... all users” seçili iken “Next” dügmesine tıkladı˘ gınızda

Kivy Mobil Programlama, Sürüm 0.2

70 Bölüm 9. Atlıkarınca ve Resim Gösterici

Page 75: Kivy Mobil Programlama - Read the Docs4 Kivy Dili: kv (kv lang) 15 ... Kivy Mobil Programlama, Sürüm 0.2 ... all users” seçili iken “Next” dügmesine tıkladı˘ gınızda

BÖLÜM 10

Liste Görünümü ve Eylem Çubugu

Bu bölümde Liste Görünümünü, Açılır Kutu (DropDown) ve Eylem Çubugu’nu anlatacagız. Konuları anlatırken dahaönce gelistirdigimiz uygulamalara eklentiler yaparak uygulamasını da gösterecegiz.

10.1 Liste Görünümü

Kivy’de listeler ve ilgili görünümler (adaptör, uyarlayıcı kullanarak), daha önce kullandıgım GUI (GKA)’lardan birazfarklı çalısıyor. Bu farklılık listelerin kullanımınız biraz zorsaltırmıs gibi görünse de, bu ona listelerin daha esnek vekullanıslı olmasını saglıyor. Ilk olarak basit bir liste olusturalım. Bu liste sadece verileri görüntülemek için kullanı-lacak, seçim yapılamayacak ve herhangi bir eylem tanımlanamayacaktır. Bir liste olusturmak için ListView nesnesinikullanırız. ListView nesnesinin en basit kullanımı paramtere olarak item_strings vermektir. Bu parametre Pythonlistesi helinde listelenecek olan elemanları alır. Programlamada dillerini listeleyecek bir programı Liste 10.1‘deki gibiyazabiliriz.

Liste 10.1: listeGorunumu.py

1 # -*- coding: utf-8 -*-2

3 from kivy.app import App4 from kivy.uix.label import Label5 from kivy.uix.boxlayout import BoxLayout6 from kivy.uix.listview import ListView7

8 class basitListeUyg(App):9

10 def build(self):11 duzen=BoxLayout()12

13 programlama_dilleri=["Perl", "PHP", "Pure", "Python", "Rebol",14 "Rexx", "Ruby", "Scheme", "Tcl"]15

16 liste = ListView(item_strings=programlama_dilleri)17

71

Page 76: Kivy Mobil Programlama - Read the Docs4 Kivy Dili: kv (kv lang) 15 ... Kivy Mobil Programlama, Sürüm 0.2 ... all users” seçili iken “Next” dügmesine tıkladı˘ gınızda

Kivy Mobil Programlama, Sürüm 0.2

18 duzen.add_widget(Label(text="Programlama Dilleri"))19 duzen.add_widget(liste)20

21 return duzen22

23 basitListeUyg().run()

Programı çalıstırdıgımızda Sekil 10.1‘de görünen pencere açılacaktır.

Sekil 10.1: Liste Görünümü (Temel)

10.1.1 SimpleListAdapter Adaptörü Kullanımı

Liste görünümlerini degistirmek ve iserlige kavusturmak için ListView nesnesine bir adaptör vermektir. Bu adaptör-lerden en basiti ise SimpleListAdapter nesnesidir. Bu adaptör sadece listelemek için kullanılır. Programlama dillerini-nin isismlerini gösteren programı bu adaptörü kullanarak tekrar yazmak istersek: Liste 10.2‘deki gibi basitListe.py dosyasını hazırlamamız gerekcek.

Liste 10.2: basitListe.py

1 # -*- coding: utf-8 -*-2

3 from kivy.app import App4 from kivy.uix.label import Label5 from kivy.uix.button import Button6 from kivy.uix.boxlayout import BoxLayout7 from kivy.adapters.simplelistadapter import SimpleListAdapter8 from kivy.uix.listview import ListView9

10 class basitListeUyg(App):11

12 def build(self):13 duzen=BoxLayout()14

15 programlama_dilleri=["Perl", "PHP", "Pure", "Python", "Rebol",16 "Rexx", "Ruby", "Scheme", "Tcl"]17

18 basit_liste_adaptoru = SimpleListAdapter(data=programlama_dilleri, cls=Button)19

20 liste = ListView(adapter=basit_liste_adaptoru)21

22 duzen.add_widget(Label(text="Programlama Dilleri"))

72 Bölüm 10. Liste Görünümü ve Eylem Çubugu

Page 77: Kivy Mobil Programlama - Read the Docs4 Kivy Dili: kv (kv lang) 15 ... Kivy Mobil Programlama, Sürüm 0.2 ... all users” seçili iken “Next” dügmesine tıkladı˘ gınızda

Kivy Mobil Programlama, Sürüm 0.2

23 duzen.add_widget(liste)24

25 return duzen26

27 basitListeUyg().run()

Simdi bu programı açıklamaya çalısalım. Programda 14. satırdaki programlama_dilleri listesi basit bir Pythonlistesidir. Görüntülemek istedigimiz elemanları bu listeye yazabiliriz. Liste yerine tüp (tuple) kullanabilirsiniz. Listegörünümünde kullanabilecegimiz en basit adaptörün SimpleListAdapter oldugunu söylemistik. Bu adaptör sa-dece bir dizi elemanı ekranda görüntülemek için kullanılabilir. Herhangi bir seçim ya da eylem gerçeklestiremezsiniz.Kullanımı oldukça basittir: paramatere olarak data (listelenecek elemanlar) ve cls (görüntüleme biçimi) alır. Görün-tüleme biçimi basit olarak bir etiket (Label) ya da dügme (Button) olabilir. Biz yukarıda etiket (Label) kullandık.Isterseniz aynı programı düpme (Button) ile tekrar çalıstırın. Program çalıstıgında yine Sekil 10.1‘de görünen pencereaçılacaktır.

Sekil 10.2‘de resimde aynı programın, listedeki görüntüleme biçiminin (cls=Button) dügme (Button) hali görün-mektedir.

Sekil 10.2: Basit Liste (Dügme)

Liste 10.2‘deki programı, c:\windows (Linux için /usr) klasöründeki dosya ve dizinleri gösterecek sekilde uyar-layınız. Linux için programınızın çalısmıs hali Sekil 10.3‘deki gibi olacaktır.

Çözüm:

basitListe-klasorler.py: https://github.com/mbaser/kivy-tr/blob/master/docs/programlar/listeEylem/programlar/1/basitListe-klasorler.py

Sonraki konuya geçmeden önce listelerin kv dili ile nasıl hazırlanacagına bakalım. Liste 10.2‘deki programımızınaynısını kv dili ile yazalım. Önce Python programını Liste 10.3‘deki gibi yazalım

Liste 10.3: basitListeKv.py

1 # -*- coding: utf-8 -*-2

3 from kivy.app import App4

5 class basitListeUyg(App):6

7 def build(self):8 pass9

10

11 basitListeUyg().run()

10.1. Liste Görünümü 73

Page 78: Kivy Mobil Programlama - Read the Docs4 Kivy Dili: kv (kv lang) 15 ... Kivy Mobil Programlama, Sürüm 0.2 ... all users” seçili iken “Next” dügmesine tıkladı˘ gınızda

Kivy Mobil Programlama, Sürüm 0.2

Sekil 10.3: Dosya ve Klasörlerin Listelenmesi (Linux)

Sanırım bu program çok kolay oldu ve herhangi bir açıklamaya ihtiyacı yok. Bu program tarafından kullanılacak kvdosyasını Liste 10.4‘de görüldügü gibi yazabiliriz.

Liste 10.4: basitlisteuyg.kv

1 #:import Label kivy.uix.label.Label2 #:import SimpleListAdapter kivy.adapters.simplelistadapter.SimpleListAdapter3

4 <basitListeUyg>:5 BoxLayout:6 Label:7 text: "Programlama Dilleri"8 ListView:9 id: listeci

10 adapter:11 SimpleListAdapter(12 data=["Perl", "PHP", "Pure", "Python", "Rebol", "Rexx", "Ruby", "Scheme",

→˓"Tcl"],13 cls=Label)

Bu kv dosyasının ilk iki stırında Label ve SimpleListAdapter nesnelerini ilgili modüllerden nasıl içerdigimiziiyice inceleyiniz. Program içerisinden adaptöre ve adaptörün verilerine ulasabilir, güncelleyebilirsiniz ve hatta baskaadaptör kullanabilirsiniz. Asagıdaki kodu build() islevinin altına yazarsanız, programlama dilleri listesine “Pascal”,“C” ve “C++” nin de eklendigini göreceksiniz:

for pr in ["Pascal", "C", "C++"]:self.root.ids.listeci.adapter.data.append(pr)

74 Bölüm 10. Liste Görünümü ve Eylem Çubugu

Page 79: Kivy Mobil Programlama - Read the Docs4 Kivy Dili: kv (kv lang) 15 ... Kivy Mobil Programlama, Sürüm 0.2 ... all users” seçili iken “Next” dügmesine tıkladı˘ gınızda

Kivy Mobil Programlama, Sürüm 0.2

10.1.2 ListAdapter Adaptörü Kullanımı

Listeler genellikle arasından birisni seçmek için kullanılır ve daha önce anlatılan basit liste görünümü olusturmaktandaha karmasık veriye sahip olabilir. Bunları ListAdapter veya DictAdapter adaptörlerini kullanarak yapabili-riz. Burada sadece ListAdapter anlatılacaktır.

Önce ListAdapter kullanımına bakalım. Daha önce söyledgimiz gibi ListView parçacıgında adaptörler, veriyi içerir.Bu veri ListAdapter için her biri birer sözlük olan Python Listesidir. Örnegin kitaplara ait veriyi ele alalım (not:kitaplar rastgele seçilmistir, seçimde herhangi bir tercih yoktur):

kitaplar=[ {'adi':'Python', 'yazari':'Mustafa Baser', 'yayinevi':'Dikeyeksen'},{'adi':'Ruby', 'yazari':'Timur Karaçay', 'yayinevi':'Seçkin'},{'adi':'Perl-CGI', 'yazari':'Rıza Çelik', 'yayinevi':'Seçkin'},{'adi':'Php', 'yazari':'Mehmet Samlı', 'yayinevi':'Kodlab'} ]

Burada kitaplar bildigimiz bir Python listesi ve elemanları bildigimiz Python sözlükleridir. Her sözlük adi,yazarı ve yayinevi anahtarları ile bunlara ait birer deger içermektedir. kitaplar listesini oldugu gibiListadapter nesnesine veri seti olarak atayabiliriz. Peki kullanıcıya ne gösterilecek? Bunu ise bir islev yadımıile belirleyebiliriz. Bu iseve argüman çevirici (arg_converter) diyoruz. Argüman çevirici kendisine gelen veriyi, listedegösterilecek sekilde düzenler ve yine bir sözlük döndürür. Bu sözlükte bulunması gereken tek zorunlu anahtar textdir. Bu anahtarın degeri kullanıcıya listede gösterilen metindir. Isterseniz gösterilecek olan liste elemanı (burada Lis-tItemButton olacaktır) (liste dügmesi) ile ilgili görünümü degistirebilirsiniz; örnegin boyutunu.

Simdi bunları birlestirelim ve seçilebilir bir liste olusturalım. Programımızı Liste 10.5‘deki gibi yazalım

Liste 10.5: kitaplar.py

1 # -*- coding: utf-8 -*-2

3 from kivy.app import App4 from kivy.uix.listview import ListView5 from kivy.adapters.listadapter import ListAdapter6 from kivy.uix.listview import ListItemButton7

8

9 class kitaplarUyg(App):10

11 def argumanCevirici(self, satir, nesne):12 return {'text': nesne["adi"], 'size_hint_y': None, 'height': 25}13

14 def build(self):15

16 kitaplar=[ {'adi':'Python', 'yazari':'Mustafa Baser', 'yayinevi':'Dikeyeksen'}→˓,

17 {'adi':'Ruby', 'yazari':'Timur Karaçay', 'yayinevi':'Seçkin'},18 {'adi':'Perl-CGI', 'yazari':'Rıza Çelik', 'yayinevi':'Seçkin'},19 {'adi':'Php', 'yazari':'Mehmet Samlı', 'yayinevi':'Kodlab'} ]20

21 liste_adaptoru=ListAdapter(args_converter=self.argumanCevirici,22 data=kitaplar,23 cls=ListItemButton,24 allow_empty_selection=False)25

26 listeGorunumu=ListView(adapter=liste_adaptoru)27

28 return listeGorunumu29

30 kitaplarUyg().run()

10.1. Liste Görünümü 75

Page 80: Kivy Mobil Programlama - Read the Docs4 Kivy Dili: kv (kv lang) 15 ... Kivy Mobil Programlama, Sürüm 0.2 ... all users” seçili iken “Next” dügmesine tıkladı˘ gınızda

Kivy Mobil Programlama, Sürüm 0.2

31

Programımızı çalıstıracak olursak Sekil 10.4‘deki gibi bir pencere açılacaktır.

Sekil 10.4: Seçilebilir Kitap Listesi

ListAdapter nesnesi arg_converter islevine (burada argumanCevirici) iki adet argüman gönderir. Bun-lardan ilki gönderilen verinin veri setindeki (data parametresine atanan deger, burada kitaplar listesi) konumu(indeksi) ikincisi ise, verinin kendisi. kitaplar listesinin her elemanı sıra ile bu isleve gönderilir. Bu isev yinebir sözlük döndürür. Sözlük en az text anahtarına sahip olmalıdır. text anahtarının degeri kullanıcıya gösteri-len metindir. Liste 10.5‘daki programda size_hint_y ve height anhatarlarını kullanarak listedeki dügmenin(ListItemButton) boytunu 25 piksel yaptık. ListItemButton nesnesi ile olusturulan dügmelerin seçilmis veseçilmemis olanların rengini de degistirebilirsiniz. Bunları deselected_color ve selected_color anahtarları ile yapabi-lirsiniz. Örnegin Liste 10.5‘daki programda argumanCevirici() islevini asagıdaki gibi yazarsanız, seçilmis olandügme rengi mor, seçilmemis olan dügmelerin rengi ise sarı olacaktır:

def argumanCevirici(self, satir, nesne):return {'text': nesne["adi"],

'size_hint_y': None, 'height': 25,'deselected_color': [1,1,0,1],'selected_color': [1,0,1,1]}

Eger kullanıcıya görüntülenecek olan dügme üzerindeki metinde, sadece kitap adı yerine yazarının da görünmesiniistiyorsanız, argumanCevirici() islevini su sekilde degistirebilirsiniz:

def argumanCevirici(self, satir, nesne):return {'text': '%s (%s)' % (nesne["adi"], nesne['yazari']),

'size_hint_y': None, 'height': 25,'deselected_color': [1,1,0,1],'selected_color': [1,0,1,1]}

Programımızı bu islev ile çalıstıracak olursak Sekil 10.5‘deki gibi bir pencere açılacaktır.

argumanCevirici() islevi sadece iki argüman alır ve bir sözlük dündürür. Bu tür bir iselev ihityacınız var isebunu Python’nun muhtesem lambda ifadesi ile gerçeklestirebilirsiniz. lambda ifadesi kendisine gelen argümanlarıbirer parametreye aktarır ve bu parametreleri kullanarak bir sonuç döndürme islevi saglar. Örnegin kendisine gelensayıları toplayan bir isleve ihtiyacımız var ise:

def topla(a,b):return a+b

yerine:

76 Bölüm 10. Liste Görünümü ve Eylem Çubugu

Page 81: Kivy Mobil Programlama - Read the Docs4 Kivy Dili: kv (kv lang) 15 ... Kivy Mobil Programlama, Sürüm 0.2 ... all users” seçili iken “Next” dügmesine tıkladı˘ gınızda

Kivy Mobil Programlama, Sürüm 0.2

Sekil 10.5: Degistirilmis Kitap Listesi

>>> topla=lambda a,b: a+b>>> topla(5,7)12

seklinde yazabiliriz. Bu bilgiler ısıgında argumanCevirici() islevini hiç yazmadan arg_cvonverter para-metresine asagıdaki gibi lambda ifadesini yazabiliriz:

liste_adaptoru=ListAdapter(args_converter=lambda satir, nesne: {'text':nesne["adi"],→˓'size_hint_y': None, 'height': 25},

data=kitaplar,cls=ListItemButton,allow_empty_selection=False)

ListAdapter parçacıgında anlatmadıgımız allow_empty_selection paramteresine False degerini verirseniz, lis-tede mutlaka bir seçim yapılmıs olması gerekir. Bu durumda seçim yapılmamıs ise, veri setinin ilk elemanı otomatikolarak seçili hale gelir. Eger allow_empty_selection degerini True yaparsanız (ön tanımlı degeri budur), lis-tede bir seçim yapma zorunlulugu olmaz.

Liste 10.5‘daki programı kv dili ile yazalım. Önce ana programı Liste 10.6‘daki gibi yazalım.

Liste 10.6: main.py

1 # -*- coding: utf-8 -*-2

3 from kivy.app import App4

5 class kitaplarUyg(App):6

7 def argumanCevirici(self, satir, nesne):8 return {'text': nesne["adi"], 'size_hint_y': None, 'height': 25}9

10 def build(self):11

12 kitaplar=[ {'adi':'Python', 'yazari':'Mustafa Baser', 'yayinevi':'Dikeyeksen'}→˓,

13 {'adi':'Ruby', 'yazari':'Timur Karaçay', 'yayinevi':'Seçkin'},14 {'adi':'Perl-CGI', 'yazari':'Rıza Çelik', 'yayinevi':'Seçkin'},15 {'adi':'Php', 'yazari':'Mehmet Samlı', 'yayinevi':'Kodlab'} ]16

17 self.root.ids.kitaplar.adapter.data=kitaplar18

19 kitaplarUyg().run()

10.1. Liste Görünümü 77

Page 82: Kivy Mobil Programlama - Read the Docs4 Kivy Dili: kv (kv lang) 15 ... Kivy Mobil Programlama, Sürüm 0.2 ... all users” seçili iken “Next” dügmesine tıkladı˘ gınızda

Kivy Mobil Programlama, Sürüm 0.2

Sanırım bu programda hersey açık. kv dosyasını ise Liste 10.7‘daki gibi hazırladım:

Liste 10.7: kitaplaruyg.kv

1 #:import ListItemButton kivy.uix.listview.ListItemButton2 #:import ListAdapter kivy.adapters.listadapter.ListAdapter3

4 <kitaplarUyg>:5 BoxLayout:6 orientation: 'vertical'7 Label:8 text: "Kitap Seçiniz"9 size_hint_y: None

10 height: 3011 canvas.before:12 Color:13 rgba: [0, 1, 0, 1]14 Rectangle:15 pos: self.pos16 size: self.size17 ListView:18 id: kitaplar19 adapter:20 ListAdapter(args_converter=app.argumanCevirici,21 data=[],22 cls=ListItemButton,23 allow_empty_selection=False)

Bu dosyayı inceleyecek olursanız, etikette ilk defa (11. satırda) canvas.before parametresini kullanmıs olduk. Neyazıkki Kivy gelistiricileri bir etiketin arka plan rengini degistirebilmemiz için bir parametre koymamıs. Bunun yerineparçacık çizilmeden önce tuvalin (canvas) arka planını boyamamız gerekir. Bunu da su satırlar ile yapıyoruz:

canvas.before:Color:

rgba: [0, 1, 0, 1]Rectangle:

pos: self.possize: self.size

10.1.3 Seçimin Denetlenmesi

En azından ListAdapter kullanılan liste görünümlerinde bir seçim yapıldıgında, bir eylem gerçeklestirilmek iste-niyorsa adaptörün on_selection_change olayına bir islev baglamak gerekir. Liste 10.6‘daki programda seçilen seçilenkitaba ait ayrıntıları açılır pencerede görüntülemek üzere build() islevinin en altına su satırı ekleyelim:

self.root.ids.kitaplar.adapter.bind(on_selection_change=self.secim)

Bir kitap seçildiginde secim() islevi çagrılacaktır. Bu isleve, adaptörün kendisi argüman olarak verilecektir. Biradaptörde seçilen maddeler ait ListItemButton nesneleri Python listesi halinde selection özelliginden alınabilir(unutmayın birden fazla seçime olanak saglamak için adatörün selection_mode parametresinin degerini multipleyapmalısınız). Seçilen maddelerin listedeki konumlarını ise ListItemButton nesnesinin index özelligi ile alabi-liriz. O halde secim islevini su sekilde yazabiliriz:

def secim(self, nesne):if nesne.selection:

secimID=nesne.selection[0].index

78 Bölüm 10. Liste Görünümü ve Eylem Çubugu

Page 83: Kivy Mobil Programlama - Read the Docs4 Kivy Dili: kv (kv lang) 15 ... Kivy Mobil Programlama, Sürüm 0.2 ... all users” seçili iken “Next” dügmesine tıkladı˘ gınızda

Kivy Mobil Programlama, Sürüm 0.2

secilenKitap=nesne.data[secimID]

icerik=Label(text='Kitap Adı: %s\nYazarı: %s\nYayınevi: %s' % (secilenKitap['adi'],secilenKitap['yazari'],secilenKitap['yayinevi']))

popup = Popup(title='Seçilen Kitap',content=icerik,size_hint=(None, None), size=(200, 150))

icerik.bind(on_touch_down=popup.dismiss)popup.open()

Asagıdaki satırları programınızın basına yazmayı unutmayın:

from kivy.uix.popup import Popupfrom kivy.uix.label import Label

Su halde programımızı çalıstırıp bir kitap seçtigimizde, bir popup açılacak ve burada kitap detayları görüntülecektir(Sekil 10.6).

Sekil 10.6: Kitap ayrıntılarının görüntülenmesi

10.1.4 Il-Ilçe-Mahalle Seçimi

Liste görünümü ile ilgili daha ayrıntılı bir örnek yapalım. Hemen birçok alısveris sitesinde bulundugunuz il ve ilçeseçimi ile ilgili açılır listeler bulunur. Biz buna bir de mahalleyi ekleyecegiz. Uygulamamız söyle tasarlayalım:

1. Ana pencereyi dikey olarak üç parçaya bölelim. Bunun için 3 sütunlu bir ızgara pencere düzenine ihtiyacımızolacak.

2. Birinci sütunda illeri gösterelim. Buranın illeri gösterdigini kullanıcıya bildirmek için etiketten bir baslık olus-turalım ve metnine “Il Seçiniz” yazalım. Etiketin altında liste görünümünde tüm illeri sıralayalım

10.1. Liste Görünümü 79

Page 84: Kivy Mobil Programlama - Read the Docs4 Kivy Dili: kv (kv lang) 15 ... Kivy Mobil Programlama, Sürüm 0.2 ... all users” seçili iken “Next” dügmesine tıkladı˘ gınızda

Kivy Mobil Programlama, Sürüm 0.2

3. Ikinci sütunda ilçeleri gösterelim. Buranın ilçeleri gösterdigini kullanıcıya bildirmek için etiketten bir baslıkolusturalım ve metnine “Ilçe Seçiniz” yazalım. Birinci sütunda seçilen ile ait ilçeleri etiketin altında liste görü-nümünde sıralayalım.

4. Üçüncü sütunda semtleri gösterelim. Buranın semtleri gösterdigini kullanıcıya bildirmek için etiketten bir baslıkolusturalım ve metnine “Semt Seçiniz” yazalım. Ikinci sütunda seçilen ilçeye ait semtleri etiketin altında listegörünümünde sıralayalım.

Uygulamamazı yazmadan önce ülkemizin illeri, bu illerin ilçeleri ve her ilçenin semtlerinin listesi gerekli. Bunu te-ker teker elinizle yazabilirsiniz. Ya benim gibi da internette “Il-ilçe-Semt-Mahalle-PostaKodu” seklinde aratırsanız,muhtemelen birçok veritabanı bulacaksınız. Aramam sonucunda su adreste:

http://daltinkurt.com/Yazi/227/Il-Ilce-Semt-Mahalle-Veritabanlari-ve-Uygulamasi.aspx

bir tane buldum. Orada birçok veritabanı biçiminde hazırlanmıs biçimlerini mevcut. Ben xml biçimini kullanacagım.Yerel kopyasını buradan edinebilirsiniz (bunun için Sn. Devrim Altınkurt’dan izin alınmıstır):

Il-ilce-Semt-Mahalle-PostaKodu.xml: https://raw.githubusercontent.com/mbaser/kivy-tr/master/docs/programlar/listeEylem/programlar/3/Il-ilce-Semt-Mahalle-PostaKodu.xml

Il-ilce-Semt-Mahalle-PostaKodu.xml dosyası oldukça büyük (~10 MB). Bu kadar büyük bir veriyi xmlile saklamak ve sonra onu okuyup ayırt etmek oldukça zaman alıcı bir islem, bu kadar büyük bir veriyi en azındaSqLite veritabanı sisteminde saklamak daha iyi. Ancak biz sadece deneme programı yazacagız, hem böylece bir xmldosyasını nasıl okuyacagınızı da ögrenmis oluruz.

Bir xml dosyasını kullanabilmek için, öncelikle dosya yapısını bilmeniz gerekir. Onun için dosyayı firefox ile açıpyapısını inceleyebiliriz (Metin düzenleyici ya da xml editörleri ile açmayı denemeyin, dosya çok büyük). Dosyayıinceledigimzde veri gruplandırmasının yapılmadıgını görüyoruz. Dosyanın yapısından anladıgımız kadarı ile asagıdakiçıkarımları yapabiliriz:

Iller <tbl_il> etiketlerinde iller mevcut. Her il için bir ID verilmis (<il_id>), il isimleri ise <il_ad> etiketiile beirtilmis.

Ilçeler Ilçelerimiz <tbl_ilce> etiketleri ile ayrılmıs. Her ilçe için bir ID verilmis (<ilce_id>). Ilçenin hangi ileait oldugu ise <il_id> etiketi ile belirtilmis. Ilçe adı ise <ilce_ad> etiketinde.

Semtler Her ilçenin semtleri <tbl_semt> etiketleri ile verilmis. Baglı oldugu ilçe <ilce_id>, semt adı ise<semt_ad> etiketi ile verilmis. Elbetteki ID’si mevcut ve <semt_id> etiketinin metninde bulunuyor.

xml Dosyasının yapısını ögrendigimize göre bu dosyayı okuyup veriyi bizim için ayır edecek Python modülünü kullan-mamız gerekir. Önce Python konsolunda bunu ögrenelim. Dosyayı bir klasöre indirin ve Python konsolundan asagıdakisatırsarı isletin:

>>> from xml.etree import ElementTree>>> agac = ElementTree.parse('/home/mbaser/Downloads/Il-ilce-Semt-Mahalle-PostaKodu.→˓xml')>>> xmlKok = agac.getroot()

Burada ikinci satırda dosya patikasını kullandıgınız isletim sistemine göre dogru sekilde belirtiniz. Dosya çok büyükoldugu için okunması donanımınızın durumuna göre birkaç saniye alabilir. Simdi illerimizi bulalım:

>>> iller=xmlKok.findall('tbl_il')

Simdi iller listesinde tüm illerimizi ait xml elemanları bulunacaktır. Bunları ekrana bastırmak için:

>>> for il in iller:... print il.find('il_id').text, il.find('il_ad').text.encode("utf-8")...1 Adana2 Adıyaman3 Afyonkarahisar

80 Bölüm 10. Liste Görünümü ve Eylem Çubugu

Page 85: Kivy Mobil Programlama - Read the Docs4 Kivy Dili: kv (kv lang) 15 ... Kivy Mobil Programlama, Sürüm 0.2 ... all users” seçili iken “Next” dügmesine tıkladı˘ gınızda

Kivy Mobil Programlama, Sürüm 0.2

4 Agrı5 Amasya6 Ankara7 Antalya8 Artvin9 Aydın10 Balıkesir...

Burada il adının UTF-8 biçimli bir metin oldugunu biliyoruz. Python 2.x’de düzgün gösterilebilmesi için metninencode("utf-8") özelligini kullanmamız gerekiyor. Bir döngüyü kullanarak istedigimiz sekilde liste olusturmayıdaha önce anlatmıstık tekrarlayalım:

>>> sayi_listesi=[ "Sayi-%d" % x for x in range(1,11)]>>> sayi_listesi['Sayi-1', 'Sayi-2', 'Sayi-3', 'Sayi-4', 'Sayi-5', 'Sayi-6', 'Sayi-7', 'Sayi-8',→˓'Sayi-9', 'Sayi-10']

Bir liste içerisinde yazdıgımız döngünün nasıl bir sonuç dogurdugunu gördük. Aynı listeyi söyle de olusturabilirdiniz:

>>> sayi_listesi=[]>>> for x in range(1,11):... sayi_listesi.append("Sayi-%d" % x)...>>> sayi_listesi['Sayi-1', 'Sayi-2', 'Sayi-3', 'Sayi-4', 'Sayi-5', 'Sayi-6', 'Sayi-7', 'Sayi-8',→˓'Sayi-9', 'Sayi-10']

Ilk yaptıgımız daha kolay degil mi? Peki iller xml elemanlarını kullanarak, liste adaptörümüz için nasıl bir verilistesi olusturacagız? Bu soruyu söyle cevaplayalım:

>>> iller_veri = [{'ilId': il.find('il_id').text, 'adi': il.find('il_ad').text.

→˓encode("utf-8")}for il in iller

]

Liste içindeki döngülerde if ifadesini de kullanabiliriz. Örnegin il_id si 10’dan küçük illerin listesini elde edelim:

>>> iller_veri = [{'ilId': il.find('il_id').text, 'adi': il.find('il_ad').text.

→˓encode("utf-8")}for il in iller if int(il.find('il_id').text) < 10

]

Bunları ögrendigimize göre, liste görünümü bilgilerini de kullanarak programımızı yazabiliriz. Önce ana programıListe 10.8‘daki gibi yazalım.

Liste 10.8: main.py

1 # -*- coding: utf-8 -*-2

3 from kivy.app import App4

5 from xml.etree import ElementTree6 agac = ElementTree.parse('Il-ilce-Semt-Mahalle-PostaKodu.xml')

10.1. Liste Görünümü 81

Page 86: Kivy Mobil Programlama - Read the Docs4 Kivy Dili: kv (kv lang) 15 ... Kivy Mobil Programlama, Sürüm 0.2 ... all users” seçili iken “Next” dügmesine tıkladı˘ gınızda

Kivy Mobil Programlama, Sürüm 0.2

7 xmlKok = agac.getroot()8

9 class illerIlceler(App):10

11 def argCevir(self, satir, nesne):12 return {'text': nesne["adi"], 'size_hint_y': None, 'height': 25}13

14 def ilSecim(self, nesne):15 if nesne.selection:16 secim=nesne.selection[0].index17 ilId=nesne.data[secim]['ilId']18

19 ilceler=xmlKok.findall('tbl_ilce')20

21 self.root.ids.ilceler.adapter.data= [22 {'ilceId': ilce.find('ilce_id').text, 'adi': ilce.

→˓find('ilce_ad').text.encode("utf-8")}23 for ilce in ilceler if ilce.find('il_id').

→˓text==ilId24 ]25

26 self.root.ids.ilceler._trigger_reset_populate()27

28 def ilceSecim(self, nesne):29 if nesne.selection:30 secim=nesne.selection[0].index31 ilceId=nesne.data[secim]['ilceId']32

33 semtler=xmlKok.findall('tbl_semt')34

35 self.root.ids.semtler.adapter.data= [36 {'semtId': semt.find('semt_id').text, 'adi': semt.find('semt_

→˓ad').text.encode("utf-8")}37 for semt in semtler if semt.find('ilce_id').text==ilceId38 ]39

40 self.root.ids.semtler._trigger_reset_populate()41

42 def build(self):43

44 iller=xmlKok.findall('tbl_il')45

46 self.root.ids.iller.adapter.data= [47 {'ilId': il.find('il_id').text, 'adi': il.find('il_ad').text.

→˓encode("utf-8")}48 for il in iller49 ]50

51 self.root.ids.iller.adapter.bind(on_selection_change=self.ilSecim)52 self.root.ids.ilceler.adapter.bind(on_selection_change=self.ilceSecim)53

54 illerIlceler().run()

Sanırım burada bilmedigimiz tek sey bir liste görünümünün _trigger_reset_populate() özelligi. Bir listegörnümünün elemanlarını degistirdiginizde, bunların ekrana yansıması için bu özelligi kullanmamız gerekiyor. Inter-net tarayıcıda degisen sayfayı yenilemek için “F5” tusuna basmak gibi.

kv dosyasını ise Liste 10.9‘daki gibi hazırladım:

82 Bölüm 10. Liste Görünümü ve Eylem Çubugu

Page 87: Kivy Mobil Programlama - Read the Docs4 Kivy Dili: kv (kv lang) 15 ... Kivy Mobil Programlama, Sürüm 0.2 ... all users” seçili iken “Next” dügmesine tıkladı˘ gınızda

Kivy Mobil Programlama, Sürüm 0.2

Liste 10.9: illerilceler.kv

1 #:import ListItemButton kivy.uix.listview.ListItemButton2 #:import ListAdapter kivy.adapters.listadapter.ListAdapter3

4 <illerIlcelerUyg>:5 GridLayout:6 cols: 37 BoxLayout:8 orientation: 'vertical'9 Label:

10 text: "Il Seçiniz"11 size_hint_y: None12 height: 3013 canvas.before:14 Color:15 rgba: 1, 0, 0, 116 Rectangle:17 pos: self.pos18 size: self.size19 ListView:20 id: iller21 adapter:22 ListAdapter(args_converter=app.argCevir,23 data=[],24 cls=ListItemButton,25 allow_empty_selection=False)26

27 BoxLayout:28 orientation: 'vertical'29 Label:30 text: "Ilçe Seçiniz"31 size_hint_y: None32 height: 3033 canvas.before:34 Color:35 rgba: 0, 1, 0, 136 Rectangle:37 pos: self.pos38 size: self.size39 ListView:40 id: ilceler41 adapter:42 ListAdapter(args_converter=app.argCevir,43 data=[],44 cls=ListItemButton,45 allow_empty_selection=False)46

47 BoxLayout:48 orientation: 'vertical'49 Label:50 text: "Semt Seçiniz"51 size_hint_y: None52 height: 3053 canvas.before:54 Color:55 rgba: 0, 0, 1, 156 Rectangle:

10.1. Liste Görünümü 83

Page 88: Kivy Mobil Programlama - Read the Docs4 Kivy Dili: kv (kv lang) 15 ... Kivy Mobil Programlama, Sürüm 0.2 ... all users” seçili iken “Next” dügmesine tıkladı˘ gınızda

Kivy Mobil Programlama, Sürüm 0.2

57 pos: self.pos58 size: self.size59 ListView:60 id: semtler61 adapter:62 ListAdapter(args_converter=app.argCevir,63 data=[],64 cls=ListItemButton,65 allow_empty_selection=False)

Bu programda her liste görnümü için yeni bir argüman çevirici yazmak yerine sadece bir tane yazdık. Bunun içintüm liste adaptarlerinin, veri setini hazırlarken görüntülenecek metni (il, ilçe, semt) adlarını adi anahtarına koyduk.Böylece liste gornümü ne olursa olsun, listede görüntülenecek metin adi anahtarında bulundugundan sadece bir taneargCevir() islevi yazmak yeterli oldu.

Programı çalıstıracak olursanız Sekil 10.7 de görünen pencere açılacaktır.

Sekil 10.7: Ile-ilçe-semt Seçimi

Not: Derleme yaparken (Paket Derleme kısmında anlatılan) buildozer in paketin içineIl-ilce-Semt-Mahalle-PostaKodu.xml dosyasını koyması için source.include_exts seçene-ginin sonuna xml eklenemsi gerekir (tüm xml uzantılı dosyalar içerilecektir):

84 Bölüm 10. Liste Görünümü ve Eylem Çubugu

Page 89: Kivy Mobil Programlama - Read the Docs4 Kivy Dili: kv (kv lang) 15 ... Kivy Mobil Programlama, Sürüm 0.2 ... all users” seçili iken “Next” dügmesine tıkladı˘ gınızda

Kivy Mobil Programlama, Sürüm 0.2

source.include_exts = py,png,jpg,kv,atlas,xml

Benim anlatacaklarım bitti. Simdi kod yazma sırası size. xml dosyasında her semte ait mahalelerde mevcut. Biz bunlarıgöstermedik. Programa mahalle seçimini de yapacagımız eklentileri yapın. Programınız çalıstıgında Sekil 10.8 dekigibi görünmeldir.

Sekil 10.8: Ile-ilçe-semt-mahalle Seçimi

Çözüm:

main-mahalleler.py: https://github.com/mbaser/kivy-tr/blob/master/docs/programlar/listeEylem/programlar/3/main-mahalleler.py illerilcelermahaller.kv: https://github.com/mbaser/kivy-tr/blob/master/docs/programlar/listeEylem/programlar/3/illerilcelermahaller.kv

10.2 Açılır Kutu

Liste görünümü ile açılır kutu (DropDown) benzer isler yapsa da, temel isleyis mantıgı olarak birbirinden farklıdır.Liste görünümünde, verdigimiz seçenekler (ister seçilebilir dügme, iseterse etiket üzerinde olsun) kullanıcıya dogru-dan gösterilir. Açılır kutularda ise, kullanıcı kutuya tıkladıktan sonra seçenekler ortaya çıkar. Önce nasıl çalıstıgınıögrenelim, daha sonra yukarıdaki örnegi açılır kutu ile tekrar yapalım.

Daha önce de belirttigim gibi Kivy’de birçok sey, bildigimiz masaüstü GUI (GKA)’lerden farklı bir yapıya sahip. Biraçılır kutuyu olusturmak için daha fazla emek harcamak gerekiyor. Örnegin bir web sayfasında açılır kutu olusturmakiçin <select> etiketi arasına seçenekleri (<option>) ard arda yazdıkmı isimiz tamamlanıyor. Ancak Kivy’de bukadar kolay degil. Bir açılır kutu olusturdugunuzda bunu pendere düzeninde öyle istediginiz yere koyamazsınız. Buaçılır kutuyu göstermek için bir baska nesneye ihtiyacınız olacak. Örnegin bir dügme. Bu dügmeye tıklayıp bıraktıgı-nızda (on_release olayı), açılır kutuyu görünür yapabilirsiniz. Aslında herhangi bir nesnenin herhangi bir olayına dabaglayabilirsiniz. Biz bir dügmeye tıklanıp bırakıldıgında açılır kutuyu gösterecegiz.

10.2. Açılır Kutu 85

Page 90: Kivy Mobil Programlama - Read the Docs4 Kivy Dili: kv (kv lang) 15 ... Kivy Mobil Programlama, Sürüm 0.2 ... all users” seçili iken “Next” dügmesine tıkladı˘ gınızda

Kivy Mobil Programlama, Sürüm 0.2

Açılır kutu nesnesi DropDown() ile olusturulur. Açılır kutunun open() özelligi ile görünür hale getirilince, ken-disine eklenmis olan diger nesneleri gösterecektir. Bu nesnelerden herhangi birisi bildiginiz dügme (Button) ya daetiket (Label) olabilir. Bunları toparlayacak olursak birkaç isimden olusan bir açılır kutuyu su sekilde olusturabiliriz:

acilirkutu = DropDown()

for isim in ( "Mustafa", "Dilek", "Fatih", "Melike"):dugme=Button(text=isim, size_hint_y=None, height=25)acilirkutu.add_widget(dugme)

Gördügünüz gibi, yaptıgımız is DropDown() nesnesine bildik dügmeleri ekledik. Peki bir dügme seçilince ne ola-cak? Programımızı yazarken bunu da eklemek durumundayız. Açılır kutuyu olusturduk ancak, bu açılır kutunungörünebilmesi için herhangi bir eyleme baglamamız gerekir. Bir dügme olusturalım (anadügme) ve bu dügmeninon_release eylemine açılır kutunun open() özelligini baglayalım. Bu bilgiler ısıgında Liste 10.10‘daki gibi birprogram yazalım.

Liste 10.10: main.py

1 # -*- coding: utf-8 -*-2

3 from kivy.app import App4 from kivy.uix.boxlayout import BoxLayout5 from kivy.uix.dropdown import DropDown6 from kivy.uix.button import Button7

8 class acilirKutu(App):9

10 def secim(self, nesne):11 self.acilirkutu.select(nesne.text)12 self.anadugme.text=nesne.text13

14 def build(self):15 duzen = BoxLayout()16 self.anadugme = Button(text='Baslat', size_hint=(None, None))17

18 self.acilirkutu = DropDown()19

20 for x in ( "Mustafa", "Dilek", "Fatih", "Melike"):21 dugme=Button(text=x, size_hint_y=None, height=25)22 dugme.bind(on_release=self.secim)23 self.acilirkutu.add_widget(dugme)24

25 self.anadugme.bind(on_release=self.acilirkutu.open)26 duzen.add_widget(self.anadugme)27

28 return duzen29

30 acilirKutu().run()

Bu programda gördügünüz gibi, açılır kutuya ekledigimiz her dügmenin on_release eylemine (tıklanıp bırkalma)secim() islevini bagladık. Diger bir deyisle açılır kutudaki dügmelerden herhangi biri seçildiginde secim() isleviçagrılacaktır. Bu islev çagrıldıgında açılır kutunun ilgili dügmesi seçilmis olacak (acilirkutu.select(nesne.text) ile) ve anadugme nin üzerindeki metin, seçilmis olan dügmenin üzerindeki metin olacaktır. Programınızçalıstıgında Sekil 10.9 deki gibi görünmelidir.

Aynı programı kv dili ile yazacak olursak:

86 Bölüm 10. Liste Görünümü ve Eylem Çubugu

Page 91: Kivy Mobil Programlama - Read the Docs4 Kivy Dili: kv (kv lang) 15 ... Kivy Mobil Programlama, Sürüm 0.2 ... all users” seçili iken “Next” dügmesine tıkladı˘ gınızda

Kivy Mobil Programlama, Sürüm 0.2

Sekil 10.9: Basit Açılır Kutu

1 # -*- coding: utf-8 -*-2

3 from kivy.app import App4 from kivy.uix.dropdown import DropDown5 from kivy.uix.button import Button6 from kivy.lang import Builder7

8 kv='''9 BoxLayout:

10 Button:11 id: anadugme12 text: "Baslat"13 on_release: app.acilirkutu.open(self)14 size_hint: (None, None)15 '''16

17 class acilirKutuKv(App):18

19 def secim(self, nesne):20 self.acilirkutu.select(nesne.text)21 self.root.ids.anadugme.text=nesne.text22

23 def build(self):24 self.root=Builder.load_string(kv)25 self.acilirkutu = DropDown()26

27 for x in ( "Mustafa", "Dilek", "Fatih", "Melike"):

10.2. Açılır Kutu 87

Page 92: Kivy Mobil Programlama - Read the Docs4 Kivy Dili: kv (kv lang) 15 ... Kivy Mobil Programlama, Sürüm 0.2 ... all users” seçili iken “Next” dügmesine tıkladı˘ gınızda

Kivy Mobil Programlama, Sürüm 0.2

28 dugme=Button(text=x, size_hint_y=None, height=25)29 dugme.bind(on_release=self.secim)30 self.acilirkutu.add_widget(dugme)31

32 return self.root33

34 acilirKutuKv().run()

Herhangi bir dügmeye herhangi bir özellik ekleyerek baska verileri saklayabiliriz. Örnegin ögrencilerin okul numara-larını saklamak için su kodu yazabiliriz:

for x, y in (("Mustafa", 9876), ("Dilek", 77192),("Fatih", 98278), ("Melike", 56765)):

dugme=Button(text=x, size_hint_y=None, height=25)dugme.okulNo=ydugme.bind(on_release=self.secim)self.acilirkutu.add_widget(dugme)

Sakladıgımız bu veriyi seçim yaptıktan sonra erisebiliriz. “Baslat” dügmesinde saçim yapıldıktan sonra hem isimhemde okul numarasını görüntülemek istiyorsak:

self.anadugme.text="Adı: %s\nNo: %d" % (nesne.text, nesne.okulNo)

10.2.1 Seçimin Denetlenmesi

Peki seçilmis maddeyi nasıl belirleyecegiz. Diger bir deyisle tekrar seçim yapılacagı zaman daha önce seçilmis olandügmeyi nasıl gösterecegiz? Liste görünümü (ListView) bunu kendisi yapıyordu, açılır kutuda bunu kendimiz yap-mamız gerekecek. Bir seçim yapıldıgında, seçilen nesnenin (burada bildigimiz dügme - Button) arka plan renginidegistirebiliriz. Bunu hemen secim() islevinin altına su satırı yazarak gerçeklestirebiliriz:

nesne.background_color= 1, 0, 0, 1

secim() islevinin altına bu satırı ekledikten sonra programı çalıstırırsanız, bir seçim yapıp tekrar seçim yapmakistediginizde önceki dügmenin arka plan renginin kırmızı oldugunu göreceksiniz. Ismiz bitti mi? Bu cevabı iknci veüçncü seçimi yaptıktan sonra siz verin. Ne oldu? Her seçilenin arkası kırmızıya dönüsüyor degil mi? Simdi çözmemizgereken baska bir sorun var. Daha önce seçilmis dügmenin arka plan rengini eski haline getirmek. Dügmelerin ön ta-nımlı arka plan rengi [1, 1, 1, 1] dir. Bunu yapmak için iki yolumuz var, ya açılır kutudaki tüm dügmelerin arkaplan rengini önce [1, 1, 1, 1] yapmak daha sonra, yeni seçilenin arka plan rengini [1, 0, 0, 1] yapmak.Ya da benim daha çok sevdigim ikinci yöntem: açılır kutuya secim özelligi verip, her seçim yapıldıgında seçilen nes-neyi buraya atamak. Böylelikle daha sonra bir açılır kutudaki seçilmis nesneye ait bilgilere de ulasabilirsiniz (aslındaçok basit ikinci yöntemi Kivy gelistiricileri neden eklemezler bilmiyorum). Bu ikinci yöntemi uygulamak için açılırkutuyu tanımladıgımız satırdan sonra (Liste 10.10‘da 19. satıra) asagıdaki satırı eklemeliyiz:

self.acilirkutu.secim=None

Bu durumda secim() islevini asagıdaki gibi degistirmemiz gerekecek:

def secim(self, nesne):# Önceden seçilmis bir dügme var ise arka plan rengini# ön tanımlı renge dönüstürelimif self.acilirkutu.secim:

self.acilirkutu.secim.background_color= [1, 1, 1, 1]

self.acilirkutu.select(nesne.text)self.anadugme.text=nesne.text

88 Bölüm 10. Liste Görünümü ve Eylem Çubugu

Page 93: Kivy Mobil Programlama - Read the Docs4 Kivy Dili: kv (kv lang) 15 ... Kivy Mobil Programlama, Sürüm 0.2 ... all users” seçili iken “Next” dügmesine tıkladı˘ gınızda

Kivy Mobil Programlama, Sürüm 0.2

# secim özelligine yeni nesneyi ekleyelim ve# arka plan rengini kırmızı yapalımself.acilirkutu.secim=nesnenesne.background_color= 1, 0, 0, 1

Üçüncü çözümü olan var mı?

10.2.2 Iller-Ilçeler-Semtler: SqLite Veritabanı

Il-ilçe-semt seçimini Il-Ilçe-Mahalle Seçimi kesiminde xml ile yapmıstık ve orada bu kadar büyük veriyi xml ile sak-lamanın çok mantıklı olmadıgını belirtmistik. Burada aynı uygulamayı liste görünümü yerine açılır kutu ile yapacagızve veritabanı olarak xml yerine SqLite kullanacagız.

SqLite oldukça hızlı, küçük (hafif), büyük veriler ile rahatlıkla basedebilen ve yaygın bir veritabanı sistemidir. Üstelikveri bir dosyada tutuldugundan degisik diller ile yazılmıs programlar rahatlıkla erisebilir ve ag üzerinden dagıtılabilir.Python ile SqLite baglantısı sqlite3 modülü ile gerçeklestirilir. Önce basitçe kullanımını hatırlayalım. Bu amaçlabir veritabanı olusturalım ve baglantısını gerçeklestirelim:

>>> import sqlite3>>> sqlbaglantisi = sqlite3.connect('ogrenciler.db')>>> isaretci = sqlbaglantisi.cursor()

ogrenciler tablosunu olusturalım:

>>> isaretci.execute('create table ogrenciler (ogr_id integer primary key, ogr_adi→˓varchar(100), ogr_no integer)')

tabloya birkaç veri ekleyelim:

>>> for x, y in (("Mustafa", 9876), ("Dilek", 77192), ("Fatih", 98278), ("Melike",→˓56765)):... isaretci.execute('insert into ogrenciler (ogr_adi, ogr_no) values ("%s", %d)'→˓% (x,y))...

Ekledigimiz verinin diske (dosyay) yazılmasını saglayalım:

>>> sqlbaglantisi.commit()

Simdi de ekledigimiz ögrencileri tekrar alalım:

>>> isaretci.execute("select * from ogrenciler")>>> ogrenciler.fetchall()>>> for ogr in ogrenciler:... print ogr...(1, u'Mustafa', 9876)(2, u'Dilek', 77192)(3, u'Fatih', 98278)(4, u'Melike', 56765)

Veritabanına yapılmıs baglantıyı koparalım:

>>> sqlbaglantisi.close()

10.2. Açılır Kutu 89

Page 94: Kivy Mobil Programlama - Read the Docs4 Kivy Dili: kv (kv lang) 15 ... Kivy Mobil Programlama, Sürüm 0.2 ... all users” seçili iken “Next” dügmesine tıkladı˘ gınızda

Kivy Mobil Programlama, Sürüm 0.2

Daha önce size verdigim Il-ilce-Semt-Mahalle-PostaKodu.xml dosyasındaki tüm tablo ve verileri SqLitebiçimine dönüstürdüm. SqLite dosyasını su adresten alabilirziniz:

iller.db: https://raw.githubusercontent.com/mbaser/kivy-tr/master/docs/programlar/listeEylem/programlar/5/iller.db

Dosyayı indirdiginiz patikanın tam adını veritabanı dosyasının patikasını yazarak deneyelim:

>>> import sqlite3>>> sqlbaglantisi = sqlite3.connect('/home/mbaser/Downloads/iller.db')>>> isaretci = sqlbaglantisi.cursor()>>> isaretci.execute("select * from tbl_il")<sqlite3.Cursor object at 0x7f3c088ebc70>>>> iller=isaretci.fetchall()>>> for il in iller:... print il[0], il[1]...1 Adana2 Adıyaman3 Afyonkarahisar4 Agrı5 Amasya...

Veritabanımız hazır olduguna göre programımızı yazabiliriz (Liste 10.11).

Liste 10.11: main.py

1 # -*- coding: utf-8 -*-2

3 from kivy.app import App4 from kivy.uix.boxlayout import BoxLayout5 from kivy.uix.dropdown import DropDown6 from kivy.uix.button import Button7

8 import sqlite39 sqlbaglantisi = sqlite3.connect('iller.db')

10 isaretci = sqlbaglantisi.cursor()11

12 class illerIlcelerAcilirKutu(App):13

14 def secimIl(self, nesne):15 if self.iller.secim:16 self.iller.secim.background_color=1, 1, 1, 117

18 self.iller.secim=nesne19 self.iller.select(nesne.text)20 self.root.ids.iller.text="Seçilen Il: %s" % nesne.text21 nesne.background_color= 1, 0, 0, 122

23 self.ilceler.clear_widgets()24 self.semtler.clear_widgets()25 self.root.ids.ilceler.text="Ilçe Seçiniz"26 self.root.ids.semtler.text="Semt Seçiniz"27

28 isaretci.execute('SELECT ilce_id, ilce_ad FROM tbl_ilce WHERE il_id=%d' %→˓nesne.il_id)

29 for ilce in isaretci.fetchall():

90 Bölüm 10. Liste Görünümü ve Eylem Çubugu

Page 95: Kivy Mobil Programlama - Read the Docs4 Kivy Dili: kv (kv lang) 15 ... Kivy Mobil Programlama, Sürüm 0.2 ... all users” seçili iken “Next” dügmesine tıkladı˘ gınızda

Kivy Mobil Programlama, Sürüm 0.2

30 dugme=Button(text=ilce[1].encode("utf-8"), size_hint_y=None, height=25)31 dugme.ilce_id=ilce[0]32 dugme.bind(on_release=self.secimIlce)33 self.ilceler.add_widget(dugme)34

35 def secimIlce(self, nesne):36

37 if self.ilceler.secim:38 self.ilceler.secim.background_color=1, 1, 1, 139

40 self.ilceler.secim=nesne41 self.ilceler.select(nesne)42 self.root.ids.ilceler.text="Seçilen Ilçe: %s" % nesne.text43 nesne.background_color= 1, 0, 0, 144

45 self.semtler.clear_widgets()46 self.root.ids.semtler.text="Semt Seçiniz"47

48 isaretci.execute('SELECT semt_id, semt_ad FROM tbl_semt WHERE ilce_id=%d' %→˓nesne.ilce_id)

49 for semt in isaretci.fetchall():50 dugme=Button(text=semt[1].encode("utf-8"), size_hint_y=None, height=25)51 dugme.semt_id=semt[0]52 dugme.bind(on_release=self.secimSemt)53 self.semtler.add_widget(dugme)54

55 def secimSemt(self, nesne):56 if self.semtler.secim:57 self.semtler.secim.background_color=1, 1, 1, 158

59 self.semtler.secim=nesne60 self.semtler.select(nesne)61 self.root.ids.semtler.text="Seçilen Semt: %s" % nesne.text62 nesne.background_color= 1, 0, 0, 163

64 def build(self):65 self.iller = DropDown()66 self.iller.secim=None67 isaretci.execute('SELECT il_id, il_ad FROM tbl_il')68 for il in isaretci.fetchall():69 dugme=Button(text=il[1].encode("utf-8"), size_hint_y=None, height=25)70 dugme.il_id=il[0]71 dugme.bind(on_release=self.secimIl)72 self.iller.add_widget(dugme)73

74 self.ilceler = DropDown()75 self.ilceler.secim=None76 self.semtler = DropDown()77 self.semtler.secim=None78

79 illerIlcelerAcilirKutu().run()

ve kv dosyası:

1 <illerIlcelerAcilirKutu>:2 BoxLayout:3 Button:4 id: iller

10.2. Açılır Kutu 91

Page 96: Kivy Mobil Programlama - Read the Docs4 Kivy Dili: kv (kv lang) 15 ... Kivy Mobil Programlama, Sürüm 0.2 ... all users” seçili iken “Next” dügmesine tıkladı˘ gınızda

Kivy Mobil Programlama, Sürüm 0.2

5 text: "Il Seçiniz"6 on_release: app.iller.open(self)7 size_hint_y: None8 height: 309

10 Button:11 id: ilceler12 text: "Ilçe Seçiniz"13 on_release: app.ilceler.open(self)14 size_hint_y: None15 height: 3016

17 Button:18 id: semtler19 text: "Semt Seçiniz"20 on_release: app.semtler.open(self)21 size_hint_y: None22 height: 30

Not: Derleme yaparken (Paket Derleme kısmında anlatılan) buildozer in paketin içine sqlite modülünü koyması içinrequirements seçeneginin su sekilde yapılandırılması gerekir:

requirements = kivy,sqlite3

Bunun dısında iller.db dosyasının içerilebilmesi için source.include_exts seçeneginin sonuna db ekle-nemsi gerekir (tüm db uzantılı dosyalar içerilecektir):

source.include_exts = py,png,jpg,kv,atlas,db

10.3 Eylem Çubugu

Mobil programlamada eylem çubugu (ActionBar), masaüstü programlardaki menu çubugu ve/veya araç çubugunabenzetelebilir (yapısal olarak farklı olasa da). Eylem çubugunu genellikle pencerinin üstüne koyarız ve programınyapılandırılması veya diger eylemler için birkaç dügme ve/veya dügme grubu koyarız. Böylelikle programın kullanıl-masını saglarız.

Bir eylem çubgu en azından bir eylem görünümü (ActionView) ve bunun içinde önceki eylem (ActionPrevious) nes-nesinden olusmalıdır. Diger bir deyisle bir eylem çubugu olusturmak için en azından ActionBar, ActionViewve ActionPrevious nesnelerini kullanmamız gerekecek. Bu bilgilerden sonra hemen bir eylem çubugu olusturanprogram yazalım (Liste 10.12)

Liste 10.12: main.py

1 # -*- coding: utf-8 -*-2

3 from kivy.app import App4 from kivy.uix.boxlayout import BoxLayout5 from kivy.uix.label import Label6

7 from kivy.uix.actionbar import ActionBar8 from kivy.uix.actionbar import ActionView9 from kivy.uix.actionbar import ActionButton

10 from kivy.uix.actionbar import ActionPrevious

92 Bölüm 10. Liste Görünümü ve Eylem Çubugu

Page 97: Kivy Mobil Programlama - Read the Docs4 Kivy Dili: kv (kv lang) 15 ... Kivy Mobil Programlama, Sürüm 0.2 ... all users” seçili iken “Next” dügmesine tıkladı˘ gınızda

Kivy Mobil Programlama, Sürüm 0.2

11

12 class eylemCubugu(App):13

14 def build(self):15

16 eylemcubugu= ActionBar(pos_hint= {'top':1})17

18 eylemgorunumu=ActionView()19 eylemcubugu.add_widget(eylemgorunumu)20

21 oncekieylem=ActionPrevious(title='Eylem Çubugu')22 eylemgorunumu.add_widget(oncekieylem)23

24 duzen = BoxLayout(orientation='vertical')25 duzen.add_widget(eylemcubugu)26

27 self.etiket=Label(text="Ana Alan")28 duzen.add_widget(self.etiket)29

30 return duzen31

32 eylemCubugu().run()

Burada gördügünüz gibi öncelikle bir eylem çubugu (ActionBar) olusturuyoruz. Bu çubugun, bulundugu alan-daki konumunu üst taraf yapmak için pos_hint parametresine {'top':1} degerini veriyoruz. Önceki eylem(ActionPrevious) nesnesinin title parametresine genellikle programın adını veriririz (unutmayın mobil ci-hazlarda pencere baslıgı olmayacaktır). Yatay yerlesimli kutu pencere düzeninin ilk elemanı eylem çubugu, ikincielemanı ise bir etiket oldu. Ikinci eleman yerine genellikle bir baska pencere düzeni koymayı yegleriz ki, programımı-zın ana penceresinde görünmesini istedigimiz nesneleri yerlestirelim. Programımızı çalıstırdıgımızda elde edecegimizpencere Sekil 10.10 ‘da verilmistir.

Sekil 10.10: Eylem Çubugu

Burada baslıgın solunda bir simgenin oldugunu görüyorsunuz. Eger önceki eylem (ActionPrevious) nesnesinin

10.3. Eylem Çubugu 93

Page 98: Kivy Mobil Programlama - Read the Docs4 Kivy Dili: kv (kv lang) 15 ... Kivy Mobil Programlama, Sürüm 0.2 ... all users” seçili iken “Next” dügmesine tıkladı˘ gınızda

Kivy Mobil Programlama, Sürüm 0.2

app_icon parametresine bir simge vermez isek ön tanımlı olarak kivy simgesi görünür. Bu simgenin nereden geldiginidaha donra açıklayacagız. Isterseniz simdi bu simgeyi degistirelim. Bunun için main.py programını kaydettiginizyere su resmi indirin:

document-edit.png: https://raw.githubusercontent.com/mbaser/kivy-tr/master/docs/programlar/listeEylem/programlar/6/document-edit.png

Daha sonra 21. satırdaki ActionPrevious nesnesinin asagıdaki gibi app_icon parametresinedocument-edit.png verin:

oncekieylem=ActionPrevious(title='Eylem Çubugu', app_icon='document-edit.png')

10.3.1 atlas

Yukarıdaki degisikligi yapıp programı çalıstırırsanız soldaki simgenin degistigini göreceksiniz. Peki bu ön tanımlısimge nereden geliyor? Cevabını vereyim atlas dan. Gerçekten atlas nesnesinden geliyor. atlas nesnesi prog-ramda kullanacagınız simgeleri bir tek resim haline getirip, bunu indeksleyip daha sonra bu simgeleri kullanma-mızı saglar. Elbetteki atlas nesnesinin ön tanımlı bir simge seti var. Kivy’nin kurulu oldugu dizindeki data/images klasöründe (benim Linux’umda tam patika /usr/lib/python2.7/dist-packages/kivy/data/images, Windows’umda tam patika C:\Python27\Lib\site-packages\kivy\data\images) bulunandefaulttheme-0.png dosyası kullanılan ön tanımlı simgelerin birlesmesinden olusan dosya, bu dosyanın ineksiise defaulttheme.atlas dosyasında bulunmaktadır. defaulttheme.atlas dosyası bildigimiz Python söz-lügüdür. Bu sözlügün içinde çesitli simge gruplarından olusan indeksler bulunur. Örnegin defaulttheme-0.png anahtarının degeri yine bir szölük ve burada simgelerin konumları bulunmaktadır. Bir örnek verecek olursakaudio-volume-medium simgesi [52, 171, 48, 48] konumunda bulunmaktadır. Bir programı apk paketihaline getirdiginizde atlas’ın ön tanımlı dosyasıda içerisinde bulundugundan buradaki simgeleri istediginiz yerde kul-lanabilirsiniz. Simdi document-edit.png yerine atlas’ın içerisinde bulunan close simgesini koyalım, bununiçin Liste 10.12 deki 21. satırı asagıdaki gibi degistirin:

oncekieylem=ActionPrevious(title='Eylem Çubugu', app_icon='atlas://data/images/→˓defaulttheme/close')

atlas’ın simgelerinin kullanımını söyle açıklayabiliriz: /atlas/icin/patika/atlas_dosyasi/simge_adi Burada suna dikkatetmelisiniz simge_adi sadece ismi içerir, dosya uzantısını içermez. Bu ön tanımlı simgeleri programınıza herhangibir ekleme yapmadan kullanabilir, öylece paketleyebilirsiniz.

Simdi kendi atlas’ımızı olusturalım. Bunun için su dosyayı indirin ve programınızın (mevcut main.py dosyasınınoldugu) patikaya açın:

simgeler.png: https://raw.githubusercontent.com/mbaser/kivy-tr/master/docs/programlar/listeEylem/programlar/6/simgeler.zip

Simdi komut satırından (cmd) asagıdaki komutu çalıstırın12 :

$ python -m kivy.atlas atlasim 256x256 simgeler/*.png

Bu komut bulundugunuz dizinde iki adet dosya olusturacaktır. Birincisi atlas indeksi (atlasim.atlas), digeri sim-gelerin birlestirildigi 256x256 boyutlarında bir PNG dosyası olan atlas resimidir (atlasim-0.png). Çalıstırdıgımızkomutun ilk kısmını zaten biliyorsunuz, atlas’ın nasıl çalıstıgını anlatalım:

• Ilk aldıgı argüman isimdir. Burada atlasim ismini verdik. Daha sonra kullanırken bu ismi yazacagız.

1 Sismteminizde PIL kurulu degil ise komut satırından su sekilde kurabilirsiniz: python -m pip install Pillow2 Windows kullanıcıları cmd yi yönetici (Administrator) yetkileri ile çalısırmaları gerekebilir. Eger Windows kullanıcıları patikaya Python’u

eklemedilerse tam patikayı yazmalıdırlar. Örnegin: C:\Python27\python.exe -m kivy.atlas atlasim 256x256 simgeler/*.png

94 Bölüm 10. Liste Görünümü ve Eylem Çubugu

Page 99: Kivy Mobil Programlama - Read the Docs4 Kivy Dili: kv (kv lang) 15 ... Kivy Mobil Programlama, Sürüm 0.2 ... all users” seçili iken “Next” dügmesine tıkladı˘ gınızda

Kivy Mobil Programlama, Sürüm 0.2

• Ikinci argüman olusturulacak atlas resminin boyutlarıdır. Eger resimleriniz büyükse daha büyük bir boyut kul-lanabilirsiniz. enxboy seklinde yazılır

• Üçüncü argüman ise atlas’a eklenecek simgelerdir. Burada bulundugumuz dizindeki simgeler dizini altındakitüm PNG dosyalarını eklemesini istedik.

Simdi olusturdugumuz atlası Liste 10.12 deki 21. satırı asagıdaki gibi degistirerek kullanalım:

oncekieylem=ActionPrevious(title='Eylem Çubugu', app_icon='atlas://atlasim/document-→˓edit')

Unutmayın atlasim-0.png ve atlasim.atlas doslayalrı Liste 10.12 programının kayıtlı oldugu dizinde ol-malıdır. Burada document-edit.png simgesini kullanmak için sadece dosya adını (document-edit) yazdıgı-mızıda aklınızdan çıkarmayın.

Olusturdugumuz atlasim.atlas ve atlasim-0.png dosyalarını suradan indirebilirsiniz:

atlasim.atlas: https://raw.githubusercontent.com/mbaser/kivy-tr/master/docs/programlar/listeEylem/programlar/6/atlasim.atlas

atlasim-0.png: https://raw.githubusercontent.com/mbaser/kivy-tr/master/docs/programlar/listeEylem/programlar/6/atlasim-0.png

Not: Derleme yaparken (Paket Derleme kısmında anlatılan), buildozer.spec dosyasında herhangi bir degisiklikyapmanıza gerek yok. Çünkü, buildozer.spec dosyasındaki source.include_exts yapılandırma seçenegiön tanımlı olarak atlas ve png doslayarını paketin içerisine koyacak sekilde yapılandırılmıstır.

10.3.2 Eylemler

Aslında eylem öncesine, tıklandıgında eylemlerin gerçeklesecegi birtakım nesnelerin yerlestirilmesi gerekiyor. Bunubildigimiz dügmeler (Button) kullanarak yapabilirsiniz. Ancak bunun yerine eylem dügmesi (ActionButton) kullan-manızı tavsiye ederim. Eylem dügmeleri, normal bir dügme gibi çalısır. Buna ilaveten bir de simge yerlestirebilirsiniz.Masaüstü programların araç çubugunda bulunan dügmelere benzetebilirsiniz. Simdi bunlardan birini ekleyelim. Bununiçin yapmanız gereken Liste 10.12 de 23. satırdan sonra sunları yazmak:

ac_eylem_dugmesi=ActionButton(text="Aç", icon='atlas://atlasim/document-open')eylemgorunumu.add_widget(ac_eylem_dugmesi)

Bu iki satırı eklediginizde, eylem çubugunun sagında üzerinde simgesinin bulundugu bir dügme eklenecektir.Elbetteki dügmemizin simdilik bir görevi yok.

Programımızı kv dili ile yazıp rahata erelim. Python programı su sekilde olmalıdır (Liste 10.13):

Liste 10.13: main.py

1 # -*- coding: utf-8 -*-2

3 from kivy.app import App4

5 class eylemCubugu(App):6

7 def build(self):8 pass9

10 eylemCubugu().run()

10.3. Eylem Çubugu 95

Page 100: Kivy Mobil Programlama - Read the Docs4 Kivy Dili: kv (kv lang) 15 ... Kivy Mobil Programlama, Sürüm 0.2 ... all users” seçili iken “Next” dügmesine tıkladı˘ gınızda

Kivy Mobil Programlama, Sürüm 0.2

ve kv dosyası (Liste 10.14):

Liste 10.14: eylemcubugu.kv

1 <eylemCubugu>:2 BoxLayout:3 orientation: 'vertical'4 pos_hint: {'top':1}5

6 ActionBar:7 ActionView:8 ActionPrevious:9 title: 'Metin Düzenleyici'

10 with_previous: False11 app_icon: 'atlas://atlasim/document-edit'12 ActionButton:13 text: 'Aç'14 id: ac_eylem_dugmesi15 icon: 'atlas://atlasim/document-open'16 ActionButton:17 text: 'Kaydet'18 id: kaydet_eylem_dugmesi19 icon: 'atlas://atlasim/document-save'20 ActionButton:21 text: 'Farklı Kaydet'22 id: farklı_kaydet_eylem_dugmesi23 icon: 'atlas://atlasim/document-save-as'24 ActionButton:25 text: 'Yeni'26 id: yeni_eylem_dugmesi27 icon: 'atlas://atlasim/document-new'28 ActionButton:29 text: 'Çık'30 id: yeni_eylem_dugmesi31 icon: 'atlas://atlasim/application-exit'32

33 Label:34 text: 'Ana Alan'

Hiçbir is yapmayan programımızı çalıstırdıgımızda Sekil 10.11 daki görüntüyü elde edecegiz.

Sanırım neden bu dügmeleri seçtigimizi anladınız. Aslında eylem dügmelerini, normal dügmeleri (Button) kullandıgı-nız yerlerin çogunda kullanma sansınız var. Burada eylem öncesi nesnesinin (ActionPrevious) simgesinin solunda “<”var idi. Bunu kaldırmak için bu nesnenin with_previous özelligine False degerini verdik.

10.3.3 Metin Düzenleyici Yeniden

Simdi hazırladıgımız eylem çubugu ile Metin Düzenleyici bölümünde hazırladıgımız metin düzenleyiciyibirlestirelim. Öncelikle kv dosyasını düzenleyelim. Bunun için metinduzenleyici.kv dosyasındaki<metinDuzenleyici>: formunda (dosyanın basındaki form) asagıdaki satırları silin:

BoxLayout:size_hint_y: 10Button:

text: "Aç"on_press: app.dosyaAcIsleviDialog()

Button:

96 Bölüm 10. Liste Görünümü ve Eylem Çubugu

Page 101: Kivy Mobil Programlama - Read the Docs4 Kivy Dili: kv (kv lang) 15 ... Kivy Mobil Programlama, Sürüm 0.2 ... all users” seçili iken “Next” dügmesine tıkladı˘ gınızda

Kivy Mobil Programlama, Sürüm 0.2

Sekil 10.11: Eylem Çubugu ve Eylem Dügmeleri

10.3. Eylem Çubugu 97

Page 102: Kivy Mobil Programlama - Read the Docs4 Kivy Dili: kv (kv lang) 15 ... Kivy Mobil Programlama, Sürüm 0.2 ... all users” seçili iken “Next” dügmesine tıkladı˘ gınızda

Kivy Mobil Programlama, Sürüm 0.2

text: "Kaydet"on_press: app.dosyaKaydetIslevi()

Button:text: "Farklı Kaydet"on_press: app.farkliKaydetDialog()

Button:text: "Yeni"on_press: app.yeniDosyaAcIslevi()

Button:id: cik_dugmesisize_hint_x: .15background_color: (0, 1, 0, 1)on_press: app.cik()

ve bunların yerine TextInput: satırından önce (exit_on_escape: False dan sonra) asagıdakileri yazın:

ActionBar:pos_hint: {'top':1}ActionView:

ActionPrevious:title: 'Metin Düzenleyici'id: eylem_oncesiwith_previous: Falseapp_icon: 'atlas://atlasim/document-edit'

ActionButton:text: 'Aç'id: ac_eylem_dugmesiicon: 'atlas://atlasim/document-open'on_press: app.dosyaAcIsleviDialog()

ActionButton:text: 'Kaydet'id: kaydet_eylem_dugmesiicon: 'atlas://atlasim/document-save'on_press: app.dosyaKaydetIslevi()

ActionButton:text: 'Farklı Kaydet'id: farklı_kaydet_eylem_dugmesiicon: 'atlas://atlasim/document-save-as'on_press: app.farkliKaydetDialog()

ActionButton:text: 'Yeni'id: yeni_eylem_dugmesiicon: 'atlas://atlasim/document-new'on_press: app.yeniDosyaAcIslevi()

ActionButton:text: 'Çık'id: cik_dugmesiicon: 'atlas://atlasim/application-exit'on_press: app.cik()

ve son olarak main.py dosyasında çıkıs dügmesinin rengini degistirdigimiz yerlerde, renk degisikligi yerine simgedegisikligi yapabilmek için su satırların yerine:

self.root.ids.cik_dugmesi.background_color = [0, 1, 0, 1]

su satırı yazın (toplam 4 satır degisiklig):

98 Bölüm 10. Liste Görünümü ve Eylem Çubugu

Page 103: Kivy Mobil Programlama - Read the Docs4 Kivy Dili: kv (kv lang) 15 ... Kivy Mobil Programlama, Sürüm 0.2 ... all users” seçili iken “Next” dügmesine tıkladı˘ gınızda

Kivy Mobil Programlama, Sürüm 0.2

self.root.ids.cik_dugmesi.icon='atlas://atlasim/application-exit'

su satır yerine:

self.root.ids.cik_dugmesi.background_color = [1, 0, 0, 1]

su satırı yazın (1 satır degisikligi):

self.root.ids.cik_dugmesi.icon='atlas://atlasim/dialog-cancel'

yapacagınız degisikliklerin hepsi bu kadar. Elbetteki atlasim.atlas ve atlasim-0.png dosyalarını metin dü-zenleyici programımızın oldugu dizine kopyalamayı unutmayacagız. Simdi metin düzenleyici programımız daha çe-kici oldu. Programımızı çalıstırdıgımızda Sekil 10.12 daki görüntüyü elde edecegiz.

Sekil 10.12: Eylem Çubuklu Metin düzenleyici

Programın son halini suradan alabilirsiniz:

atlasim.atlas: https://raw.githubusercontent.com/mbaser/kivy-tr/master/docs/programlar/listeEylem/programlar/8/atlasim.atlas

atlasim-0.png: https://raw.githubusercontent.com/mbaser/kivy-tr/master/docs/programlar/listeEylem/programlar/8/atlasim-0.png

10.3. Eylem Çubugu 99

Page 104: Kivy Mobil Programlama - Read the Docs4 Kivy Dili: kv (kv lang) 15 ... Kivy Mobil Programlama, Sürüm 0.2 ... all users” seçili iken “Next” dügmesine tıkladı˘ gınızda

Kivy Mobil Programlama, Sürüm 0.2

main.py: https://raw.githubusercontent.com/mbaser/kivy-tr/master/docs/programlar/listeEylem/programlar/8/main.py

metinduzenleyici.kv: https://raw.githubusercontent.com/mbaser/kivy-tr/master/docs/programlar/listeEylem/programlar/8/metinduzenleyici.kv

Soru: Sekil 10.12 deki ekran görüntüsününde eylem öncesi nesnesinin baslıgı, açılan (ya da kaydedilen) dosya-nın dosya adını göstermektedir. Bunu siz de yapabilirmisiniz? Ipucu: self.root.ids.eylem_oncesi.titlemetnini dosya adı yapmalısınız.

Metin düzenleyicinin son halini derledim ve denemeniz için asagıdaki köprüye koydum:

https://raw.githubusercontent.com/mbaser/kivy-tr/master/docs/programlar/listeEylem/programlar/8/kivymetinduzenleyici-0.3.apk

Programın Android öykünücüdeki çalısan hali ise söyle:

Sekil 10.13: Android öykünücüde çalısan Metin Düzenleyici

10.3.4 Eylem Dügmelerini Ayırma ve Gruplama

Eylem dügmeleri arasına ayıraç koyarak, tıpkı masaüstü programlarda bulunan araç çubuklarında oldugu gibi, birbi-rinden ayırabilirsiniz. Ayıraç koymak istediginiz dügmelerin arasına (kv dosyasında) ActionSeparator nesnesi koy-

100 Bölüm 10. Liste Görünümü ve Eylem Çubugu

Page 105: Kivy Mobil Programlama - Read the Docs4 Kivy Dili: kv (kv lang) 15 ... Kivy Mobil Programlama, Sürüm 0.2 ... all users” seçili iken “Next” dügmesine tıkladı˘ gınızda

Kivy Mobil Programlama, Sürüm 0.2

malısınız. Örnegin “Kaydet” ve “Farklı Kaydet” arasına ayıraç koymak için metinduzenleyici.kv dosyasınınActionBar kısımını asagıdaki gibi düzenleyebilirsiniz:

ActionBar:pos_hint: {'top':1}ActionView:

ActionPrevious:title: 'Metin Düzenleyici'id: eylem_oncesiwith_previous: Falseapp_icon: 'atlas://atlasim/document-edit'

ActionButton:text: 'Aç'id: ac_eylem_dugmesiicon: 'atlas://atlasim/document-open'on_press: app.dosyaAcIsleviDialog()

ActionSeparator:ActionButton:

text: 'Kaydet'id: kaydet_eylem_dugmesiicon: 'atlas://atlasim/document-save'on_press: app.dosyaKaydetIslevi()

ActionButton:text: 'Farklı Kaydet'id: farklı_kaydet_eylem_dugmesiicon: 'atlas://atlasim/document-save-as'on_press: app.farkliKaydetDialog()

ActionSeparator:ActionButton:

text: 'Yeni'id: yeni_eylem_dugmesiicon: 'atlas://atlasim/document-new'on_press: app.yeniDosyaAcIslevi()

ActionButton:text: 'Çık'id: cik_dugmesiicon: 'atlas://atlasim/application-exit'on_press: app.cik()

Eylem dügmelerini gruplamak için ActionGroup nesnesini kullanabilirsiniz. Bu nesnenin mode parametresi grupla-manın nasıl yapılacagını belirtir. Ön tanımlı degeri normal dir ve ekranda yer olmadıgı zaman gruplama yapar. Yeterikadar yer var ise gruplamadan gösterir. Degerini spinner yaparsanız her zaman gruplanır ve simgeler yerine metingösterilir. Elebetteki text parametresine grup metnini belirtmeliyiz. Asagıda metinduzenleyici.kv dosyasınınActionBar kısımında nasıl kullanılacagı gösterilmistir:

ActionBar:pos_hint: {'top':1}ActionView:

ActionPrevious:title: 'Metin Düzenleyici'id: eylem_oncesiwith_previous: Falseapp_icon: 'atlas://atlasim/document-edit'

ActionButton:text: 'Aç'id: ac_eylem_dugmesiicon: 'atlas://atlasim/document-open'on_press: app.dosyaAcIsleviDialog()

10.3. Eylem Çubugu 101

Page 106: Kivy Mobil Programlama - Read the Docs4 Kivy Dili: kv (kv lang) 15 ... Kivy Mobil Programlama, Sürüm 0.2 ... all users” seçili iken “Next” dügmesine tıkladı˘ gınızda

Kivy Mobil Programlama, Sürüm 0.2

ActionGroup:text: 'Kaydetme'mode: 'normal'ActionButton:

text: 'Kaydet'id: kaydet_eylem_dugmesiicon: 'atlas://atlasim/document-save'on_press: app.dosyaKaydetIslevi()

ActionButton:text: 'Farklı Kaydet'id: farklı_kaydet_eylem_dugmesiicon: 'atlas://atlasim/document-save-as'on_press: app.farkliKaydetDialog()

ActionButton:text: 'Yeni'id: yeni_eylem_dugmesiicon: 'atlas://atlasim/document-new'on_press: app.yeniDosyaAcIslevi()

ActionButton:text: 'Çık'id: cik_dugmesiicon: 'atlas://atlasim/application-exit'on_press: app.cik()

Sekil 10.14 de üsstteki resimde pencere yeteri kadar genisken eylem dügmelerinin gruplanmamıs hali, alttaki resimdeise pencere daraltıldıgında gruplanmıs hali görünüyor. Gruplanmıs eylem dügmeleri eylem çubugunun en sagında yeralır.

Sekil 10.14: Üstte gruplanmamıs, altta gruplanmıs eylem dügmeleri

102 Bölüm 10. Liste Görünümü ve Eylem Çubugu

Page 107: Kivy Mobil Programlama - Read the Docs4 Kivy Dili: kv (kv lang) 15 ... Kivy Mobil Programlama, Sürüm 0.2 ... all users” seçili iken “Next” dügmesine tıkladı˘ gınızda

Kivy Mobil Programlama, Sürüm 0.2

Dipnotlar

10.3. Eylem Çubugu 103

Page 108: Kivy Mobil Programlama - Read the Docs4 Kivy Dili: kv (kv lang) 15 ... Kivy Mobil Programlama, Sürüm 0.2 ... all users” seçili iken “Next” dügmesine tıkladı˘ gınızda

Kivy Mobil Programlama, Sürüm 0.2

104 Bölüm 10. Liste Görünümü ve Eylem Çubugu

Page 109: Kivy Mobil Programlama - Read the Docs4 Kivy Dili: kv (kv lang) 15 ... Kivy Mobil Programlama, Sürüm 0.2 ... all users” seçili iken “Next” dügmesine tıkladı˘ gınızda

BÖLÜM 11

Sekmeli Panel (TabbedPanel) ve Agaç Görünümü (TreeView)

Kivy’de sekmeler, diger GUI’lerde oldugu gibi bir pencerede birden fazla sayfa görünümünü sunmak için kullanı-lır. Kivy’de Sekmeli Panel (TabbedPanel) olarak isimlendirilir. Olusturuldugunda size ön tanımlı olarak Defaultsekmesini sunacaktır.

11.1 Kod ile Sekmeli Panel Olusturulması

Her zaman oldugu gibi, öncelikle kod ile nasıl sekmeli panel olusturacagımızı görecegiz. Sözü fazla uzatmadan hemenörnek kodumuzu verelim, programımızı Liste 11.1‘deki gibi yazalım.

Liste 11.1: main.py

1 # -*- coding: utf-8 -*-2

3 from kivy.app import App4 from kivy.uix.label import Label5 from kivy.uix.tabbedpanel import TabbedPanel, TabbedPanelHeader6 from kivy.lang import Builder7

8 class sekmeliPanel(App):9

10 def build(self):11 sekmeli_panel = TabbedPanel()12

13 sekmeli_panel.default_tab.text="Ilk Sekme"14

15 sekmeli_panel.default_tab.content=Label(text="Sekmeli Panel'in Ilk sayfası")16

17 for i, isim in enumerate(('Dilek', 'Fatih', 'Melike')):18 sekme=TabbedPanelHeader(text='Sekme %d' % (i+1))19 sekme.content=Label(text="Bu sekmenin sahibi: %s" % isim)20 sekmeli_panel.add_widget(sekme)21

22 return sekmeli_panel

105

Page 110: Kivy Mobil Programlama - Read the Docs4 Kivy Dili: kv (kv lang) 15 ... Kivy Mobil Programlama, Sürüm 0.2 ... all users” seçili iken “Next” dügmesine tıkladı˘ gınızda

Kivy Mobil Programlama, Sürüm 0.2

23

24 sekmeliPanel().run()

Simdi burada olup biteni anlamaya çalısalım. Bir sekmeli panel TabbedPanel() parçacıgı ile olusturulur. Bir sek-meli panle olusur olusmaz ön tanımlı olarak default panel ile olustur ve bu ön tanımlı sekme sekme parçacıgınınözelliklerine default_tab ın text ve content özelliklerini kullarak yapabilirsiniz. Aslında bunu default_tab_textve default_tab_content ile de yapmanız mümkün ancak ben öncekini tercih ediyorum. Bunlardan ilki sekme baslı-gını ikincisi sekmenin içerigini belirtir. Programımızda ön tanımlı sekmenin baslıgını Ilk Sekme içerigini ise biretiketten olusturduk (etiket metinini açıklamaya gerek yok sanırım). Eger ön tanımlı sekmeyi istemiyorsanız, sek-meli paneli olustururken do_default_tab parametresinin degerini False yapmalısınız. Diger bir deyisye, ön tanımlısekmesi olmayan bir sekmeli paneli su sekilde tanımlayabilirdik:

sekmeli_panel = TabbedPanel(do_default_tab=False)

Sekmeli Panele yeni sekmeler eklemek için, öncelikle bu sekmeyi hazırlamanız gerekir. Bunu sekme parçacıgı Tab-bedPanelHeader() kullanarak yaparız. Bu parçacıgın text özelligi sekmenin baslıgını gösterir. Içerigini ise, contentözelligi ile olusturabilirsiniz. content özelligine istediginiz bir pencere düzeni atayabilirsiniz. Burada basit olsundiye sadece bir etiket atadık.

Programımız önce ön tanımlı sekme olusturuyor. Daha sonra bir sekme baslıkları “Sekme <sayi>” ve sekme içerik-lerindeki etiketlerin metinleri “Bu sekmenin sahibi: <isim>” olacak sekilde yeni sekme parçacıkları olusturup bunlarıSekmeli Panele ekliyor. Programımız çalıstıgında Sekil 11.1‘deki gibi olacaktır.

Sekil 11.1: Dört sekmeli panel

Simdi biraz olaylara bakalım. Ilk olarak ön tanımlı sekmeye geçis yapıldıgında olusan olayı bir iseleve baglayalım:

106 Bölüm 11. Sekmeli Panel (TabbedPanel) ve Agaç Görünümü (TreeView)

Page 111: Kivy Mobil Programlama - Read the Docs4 Kivy Dili: kv (kv lang) 15 ... Kivy Mobil Programlama, Sürüm 0.2 ... all users” seçili iken “Next” dügmesine tıkladı˘ gınızda

Kivy Mobil Programlama, Sürüm 0.2

sekmeli_panel.default_tab.bind(on_release = self.sekmeDegistirildi)

Bu satırı return den hemen önce yazabilirsiniz. sekmeDegistirildi() islevini de su sekilde yazalım:

def sekmeDegistirildi(self,sekme):popup = Popup(title='Sekme Degistirildi',

content=Label(text= "Sekme Baslıgı: "+sekme.text),size_hint=(None, None), size=(200, 200))

popup.open()

Bu islevi yazdıktan sonra programınızın basına asagıdaki saırı yazarak Popup perçacaıgını içermelisiniz:

from kivy.uix.popup import Popup

Simdi programınızı çalısrırın ve bir sekmeye geçtikten sonra tekrar ön tanımlı sekmeye geçis yapın. Popup penceresaçılacaktır. Isterseniz tüm sekmelere geçis yaptıgınızda bu popup penceresini görüntülemek için for döngü blogunubtirmeden önce asagıdaki satırı ekleyebilirsiniz:

sekme.bind(on_release = self.sekmeDegistirildi)

11.2 kv Dili ile Sekmeli Panel Olusturulması

Simdi kv dili ile nasıl sekme olusturabilecegimize bakalım. Sekmeli panleimizde hiçbir islev yapmadan sadece olus-turalım. Ilk olarak programımızı Liste 11.2‘deki gibi yazalım.

Liste 11.2: main.py

1 # -*- coding: utf-8 -*-2

3 from kivy.app import App4 from kivy.uix.label import Label5 from kivy.uix.tabbedpanel import TabbedPanel, TabbedPanelHeader6 from kivy.lang import Builder7 from kivy.uix.popup import Popup8

9 class sekmeliPanel(App):10

11 def build(self):12 pass13

14 sekmeliPanel().run()

kv dosyasını da Liste 11.3‘deki gibi yazalım.

Liste 11.3: sekmelipanel.kv

1 TabbedPanel:2 do_default_tab: False3

4 TabbedPanelItem:5 text: 'Ilk Sekme'6 Label:7 text: 'Burası ilk sekme'8

9 TabbedPanelItem:

11.2. kv Dili ile Sekmeli Panel Olusturulması 107

Page 112: Kivy Mobil Programlama - Read the Docs4 Kivy Dili: kv (kv lang) 15 ... Kivy Mobil Programlama, Sürüm 0.2 ... all users” seçili iken “Next” dügmesine tıkladı˘ gınızda

Kivy Mobil Programlama, Sürüm 0.2

10 text: 'Iknci Sekme'11 BoxLayout:12 Label:13 text: 'Ikinci sekme'14 Button:15 text: 'Islevsiz Dügme'16

17 TabbedPanelItem:18 text: 'Üçüncü Sekme'19 Image:20 source: "kiwi.jpg"21 allow_stretch: True22 keep_ratio: False23

Burada gördügünüz gibi ikinci sekemede bir etiket ve bir islevsiz dügme bulunmaktadır. Son sekemde ise sadece birresim bulunuyour. main.py programını çalıstıracak olursak, Sekil 11.2‘deki gibi olacaktır.

11.3 Agaç Görünümü (TreeView)

Aslında agaç görünümüne daha önceden tanıs olduk. Dosya açma diyalogunda (Aç) kullandıgımızFileChooserListView modülünde agaç görünümü kullanılmaktadır. Bir agaç görünümü su sekildedir:

Kök|+--Ebeveyn 1| || +--Çocuk 1 1| || +--Çocuk 1 2| || +--Çocuk 1 2 1| || +--Çocuk 1 2 2|+--Ebeveyn 2

|+--Çocuk 2 1|+--Çocuk 2 2

Burada her ebeveynin kendi çocugu vardır. Simdi böyle bir yapıyı nasıl olusturacagımıza bakalım. Önce program ilenasıl yapılacagına bakacagız. Liste 11.4‘deki programı inceleyin

Liste 11.4: main.py

1 # -*- coding: utf-8 -*-2

3 from kivy.app import App4

5 from kivy.uix.treeview import TreeView, TreeViewLabel6

7 class agacGorunumu(App):8

9 def build(self):10 agac_koku = TreeView()

108 Bölüm 11. Sekmeli Panel (TabbedPanel) ve Agaç Görünümü (TreeView)

Page 113: Kivy Mobil Programlama - Read the Docs4 Kivy Dili: kv (kv lang) 15 ... Kivy Mobil Programlama, Sürüm 0.2 ... all users” seçili iken “Next” dügmesine tıkladı˘ gınızda

Kivy Mobil Programlama, Sürüm 0.2

Sekil 11.2: Dört sekmeli panel

11.3. Agaç Görünümü (TreeView) 109

Page 114: Kivy Mobil Programlama - Read the Docs4 Kivy Dili: kv (kv lang) 15 ... Kivy Mobil Programlama, Sürüm 0.2 ... all users” seçili iken “Next” dügmesine tıkladı˘ gınızda

Kivy Mobil Programlama, Sürüm 0.2

11 ebeveyn1=agac_koku.add_node(TreeViewLabel(text='Ebeveyn 1'))12

13 cocuk11=agac_koku.add_node(TreeViewLabel(text='Çocuk 1 1'), ebeveyn1)14 cocuk12=agac_koku.add_node(TreeViewLabel(text='Çocuk 1 2'), ebeveyn1)15

16 cocuk121=agac_koku.add_node(TreeViewLabel(text='Çocuk 1 2 1'), cocuk12)17 cocuk122=agac_koku.add_node(TreeViewLabel(text='Çocuk 1 2 2'), cocuk12)18

19 ebeveyn2=agac_koku.add_node(TreeViewLabel(text='Ebeveyn 2'))20 cocuk21=agac_koku.add_node(TreeViewLabel(text='Çocuk 2 1'), ebeveyn2)21 cocuk22=agac_koku.add_node(TreeViewLabel(text='Çocuk 2 2'), ebeveyn2)22

23

24 return agac_koku25

26 agacGorunumu().run()

Bir agaç kökü TreeView() nesnesi ile olusturulur. Daha sonra ebeveynler ve çocuklar bu agaç köküne add_nodeile eklenir. Eklenen her elemana dügüm (node) diyoruz. Tüm ebeveynler ve çocuklar agaç köküne eklenir, yani bek-lendigi gibi, çocuklar önceki ebeveynlerine degil, dogrudan agaç köküne eklenir, ancak hangi ebeyene eklenecegi,add_node() isevinin ikinci argümanı olarak belirtilir. Eger argüman berlirtilemz ise, dogrudan köke eklenir. Prog-ramımızı çalıstırdıgımızda Sekil 11.3‘deki gibi bir görüntü elde ederiz.

Sekil 11.3: Agaç görünümü

Elimizdeki veriseti ile bir agaç kökünü Liste 11.5‘deki gibi doldurabiliriz:

110 Bölüm 11. Sekmeli Panel (TabbedPanel) ve Agaç Görünümü (TreeView)

Page 115: Kivy Mobil Programlama - Read the Docs4 Kivy Dili: kv (kv lang) 15 ... Kivy Mobil Programlama, Sürüm 0.2 ... all users” seçili iken “Next” dügmesine tıkladı˘ gınızda

Kivy Mobil Programlama, Sürüm 0.2

Liste 11.5: main.py

1 # -*- coding: utf-8 -*-2

3 from kivy.app import App4

5 from kivy.uix.treeview import TreeView, TreeViewLabel6 from kivy.uix.boxlayout import BoxLayout7 from kivy.uix.button import Button8

9 class agacGorunumu(App):10

11 def build(self):12 duzen=BoxLayout(orientation='vertical')13

14 self.agac_koku = TreeView(hide_root=True)15

16 kuruyemisler=[('Sert Kabuklular',('Ceviz', 'Fındık', 'Badem')),17 ('Meyve Kuruları',('Dut', 'Visne', 'Kayısı', 'Incir'))]18

19 for ky in kuruyemisler:20 eb=self.agac_koku.add_node(TreeViewLabel(text=ky[0]))21 for k in ky[1]:22 self.agac_koku.add_node(TreeViewLabel(text=k),eb)23

24 duzen.add_widget(self.agac_koku)25

26 return duzen27

28

29 agacGorunumu().run()

Bu programda agaç kökünü hide_root ile gizledigimize dikkat ediniz.

Peki seçilen elemana ya da tüm elemanlara nasıl ulasacagız? Dügümler üzerinde iterasyonu iterate_all_nodes() ileyapabiliriz. Liste 11.5‘deki programdaki elemanlara ulasmak için önce düzenimize bir dügme ekleyelim. Asagıdakikodu return den hemen önce yazın:

dgm=Button(text='Elemanları Yaz', size_hint_y=0.2)dgm.bind(on_press=self.elemanlari_yaz)duzen.add_widget(dgm)

Daha sonra dügmeye tıklandıgında çagrılacak olan islevi yazalım:

def elemanlari_yaz(self, *args):for eb in self.agac_koku.iterate_all_nodes():

print eb.level, eb.text

Dügmeye tıkladıgımızda ekrana elemanların konumları ve elemanlar yazılacaktır.

Eger seçili olan elemana ulasmak istiyorsanız selected_node() özelligini kullanabilirsiniz. Asagıdaki satırıelemanlari_yaz() islevinin sonuna ekleyin ve dügmeye tıklayın:

if self.agac_koku.selected_node:print "Seçili Eleman", self.agac_koku.selected_node.text

Eger önceden bir dügümü açılı yapmak istiyorsanız select_node özelligini kullanabilirsiniz. Örnegin

11.3. Agaç Görünümü (TreeView) 111

Page 116: Kivy Mobil Programlama - Read the Docs4 Kivy Dili: kv (kv lang) 15 ... Kivy Mobil Programlama, Sürüm 0.2 ... all users” seçili iken “Next” dügmesine tıkladı˘ gınızda

Kivy Mobil Programlama, Sürüm 0.2

112 Bölüm 11. Sekmeli Panel (TabbedPanel) ve Agaç Görünümü (TreeView)

Page 117: Kivy Mobil Programlama - Read the Docs4 Kivy Dili: kv (kv lang) 15 ... Kivy Mobil Programlama, Sürüm 0.2 ... all users” seçili iken “Next” dügmesine tıkladı˘ gınızda

BÖLÜM 12

Pencere Yöneticisi (ScreenManager)

Kivy’de sekmeler, diger GUI’lerde alısık olmadıgımız pencere yöneticisi bulunmaktadır. Belki de yıgın lara (stac-ked widget) benzetebiliriz, ancak tam olarak eslenigi sayılamaz. Pencere yöneticisi tıpkı bir sunumdaki salyatlara dabenzetleblir. Birden çok pencere düzennin arka arakya, yada istenilen herhangi bir sırada ekrana yansılıması olaraktanımlayabiliriz. Bazı Kivy programcıları atlı karınca iel pencere yönetcisi arasında seçim zorlugu da yasamaktadırlar.Ancak pencere yönetici, bence diger GUI’lerde de olması gereken muhtesem bir yaıpıdır. Pencere yöneticisi sayesinde,Kivy ile kiosk tipi uygulalamaların gesistirilmesi mümkün olabilmektedir.

12.1 Kod ile Pencere Yöneticisi

Pencere yöneticisini, kod ile hazırlayıp, her pencerenin içerigini kv dili ile yazarız. Ancak nasıl çalıstıgını anlamakiçin öncelikle bir pencere yöneticisi oldusturalım ve bu pencereye sadece birer etiketden olusan pecnereler ekleyelim.Pencere yöneticisi ScreenManager parçacıgı ile olusturulur. Bu parçacıga eklenecek olan pencereler ise Screenparçacıklarıdır. Bu açıklamalrdan sonra Liste 12.1‘deki gibi bir program yazalım.

Liste 12.1: main.py

1 # -*- coding: utf-8 -*-2

3 from kivy.app import App4 from kivy.uix.label import Label5 from kivy.uix.screenmanager import ScreenManager, Screen6 from kivy.clock import Clock7

8 class PencereUyg(App):9

10 def build(self):11 self.py=ScreenManager()12

13 for i in range(4):14 p=Screen(name="pncr%d" % i)15 p.add_widget(Label(text="Pencere %d" % i))16 self.py.add_widget(p)

113

Page 118: Kivy Mobil Programlama - Read the Docs4 Kivy Dili: kv (kv lang) 15 ... Kivy Mobil Programlama, Sürüm 0.2 ... all users” seçili iken “Next” dügmesine tıkladı˘ gınızda

Kivy Mobil Programlama, Sürüm 0.2

17 self.py.current = 'pncr2'18 Clock.schedule_interval(self.pencereDegistir, 2)19 return self.py20

21 def pencereDegistir(self, *args):22 sonraki = self.py.next()23 self.py.current = sonraki24

25 PencereUyg().run()

Bu programı açıklamaya çalısalım. Eger pencere yöneticisi kullanacaksanız, build() islevi mutlakaScreenmanager() parçacıgı döndürmelidir. Pencere yöneticisine ekleyecegimiz her parçacık Screen() olmalıdır.Screen() parçacıgı, ekranda bagımsız bir pencere olarak görünecektir. Her pencereye mutalak bir isim vermelisi-niz. Bunu name parametresi ile yapıyoruz. Daha sonra istediginiz pencreye ait elemanlara erismek veye bu pencereyiekrenda görüntülemek için bu ismi kullancakagız. Yukarıdaki programda pencereler, for iterasyonunun altında yapıl-dıgında pencerelerin isimleri sıra ile pncr0, pncr1, pncr2 ve pncr3 olmak üzere dört adet pencere eklenmistir.Her pencereye yukarıda yaptıgımız gibi tek bir parçacık ekleyecekseniz, bunu dogrudan add_widget() ile yapa-bilirsiniz. Birden fazla parçacık barındıracak ise bunları herhengi bir pencere düzenine (Layout) ekleyip daha sonrabu pencere düzenin, pencreye eklemelisiniz. Yukarıdaki programda pencereler arasında geçis yapabilmek için zaman-yalyıcı kullandık. Bunu daha önce açıklamıstık. Zamanlayıcının her tık deyisinde isletilen pencereDegistir()islevinde her seferinde sonraki pencereye geçis yapılmaktadır. Gösterilen pencereden sonraki pencerenin ismini, yö-neticinin next() islevi ile alabilirsiniz. pencereDegistir() islevinde gösterilen penceredn sonraki pencere adısonraki degiskenine aktarılmıs, sonraki satırda ise, gösterilecek pencere yöneticinin current özelligine atanmıstır.current hem atama yapılan hemde degeri çagrılan bir islevdir, o anda gösterilen pencerenin ismini barındırır.

12.2 Pencerelerin Kv Dili ile Hazırlanması

Her pencereyi ayrı ayrı kv dili ile hazırlayıp bunları pencere yöneticisine ekleyebiliriz. Öncelikle asagıdaki üç pence-reyi hazırlayalım:

Liste 12.2: duyuru.kv

1 <duyuruPenceresi>:2 name: 'duyuru'3 BoxLayout:4 orientation: 'vertical'5 Label:6 text: 'Duyurular'7 font_size: 308 Label:9 id: duyuru_etiketi

10 text_size: self.size11 valign: 'middle'12 font_size: 2513 line_height: 2

Liste 12.3: atasozu.kv

1 <atasozuPenceresi>:2 name: 'atasozu'3 BoxLayout:4 orientation: 'vertical'5 Label:6 text: 'Bir Atasözü'

114 Bölüm 12. Pencere Yöneticisi (ScreenManager)

Page 119: Kivy Mobil Programlama - Read the Docs4 Kivy Dili: kv (kv lang) 15 ... Kivy Mobil Programlama, Sürüm 0.2 ... all users” seçili iken “Next” dügmesine tıkladı˘ gınızda

Kivy Mobil Programlama, Sürüm 0.2

7 font_size: 308 Label:9 id: atasozu_etiketi

10 font_size: 25

Liste 12.4: resim.kv

1 <resimPenceresi>:2 name: 'resim'3 BoxLayout:4 orientation: 'vertical'5 Label:6 text: 'Bir Resim'7 font_size: 308 Image:9 id: resim

10 source:''11 Label:12 text: ''13 id: resim_etiketi

Bu dosyalarda, simdiye kadar farklı olarak yazdıgımız sadece name belirteçleridir. Digerlerini daha önceden biliyoruz.

programımız:

Liste 12.5: main.py

1 # -*- coding: utf-8 -*-2

3 from kivy.app import App4 from kivy.lang import Builder5 from kivy.uix.screenmanager import ScreenManager, Screen6 from kivy.clock import Clock7 import random8

9 class duyuruPenceresi(Screen):10 pass11

12 class atasozuPenceresi(Screen):13 pass14

15 class resimPenceresi(Screen):16 pass17

18 atasozleri=[19 'Abanın kadri yagmurda bilinir.',20 'Acı patlıcanı kıragı çalmaz.',21 'Aç bırakma hırsız edersin, çok söyleme arsız (yüzsüz) edersin.',22 'Misafir on kısmetle gelir; birini yer dokuzunu bırakır.'23 ]24

25 resimler=[26 ('kiraz.jpg', 'Ilçemizde bu yıl kiraz verimin yüksek olacagı beklenmektedir'),27 ('seftali.jpg', 'Ilçemizde yetisen Seftali\'ler tüm dünyaya satılıyor'),28 ('cilek.jpg', 'Çilek mevsimi geldi. Bol vitamin için çilek yiyin')29 ]30

31 class IlanPanosuUyg(App):

12.2. Pencerelerin Kv Dili ile Hazırlanması 115

Page 120: Kivy Mobil Programlama - Read the Docs4 Kivy Dili: kv (kv lang) 15 ... Kivy Mobil Programlama, Sürüm 0.2 ... all users” seçili iken “Next” dügmesine tıkladı˘ gınızda

Kivy Mobil Programlama, Sürüm 0.2

32

33 def build(self):34 self.py=ScreenManager()35

36 Builder.load_file("duyuru.kv")37 Builder.load_file("atasozu.kv")38 Builder.load_file("resim.kv")39 self.py.add_widget(duyuruPenceresi(name='ilan'))40 self.py.add_widget(atasozuPenceresi(name='atasozu'))41 self.py.add_widget(resimPenceresi(name='resim'))42

43 Clock.schedule_interval(self.pencereDegistir, 2)44

45 return self.py46

47

48 def pencereDegistir(self, *args):49 sonraki = self.py.next()50 pcr = self.py.get_screen(sonraki)51 if sonraki == 'duyuru':52 pcr.ids['duyuru_etiketi'].text = ' *Önümüzdeki hafta sonu veli toplantısı

→˓yapılacaktır.\n *Yarın gezi kolu Pamukkale\'ye gidecektir.'53 elif sonraki == 'atasozu':54 pcr.ids['atasozu_etiketi'].text = random.choice(atasozleri)55 elif sonraki == 'resim':56 res = random.choice(resimler)57 pcr.ids['resim'].source = res[0]58 pcr.ids['resim_etiketi'].text = res[1]59

60 self.py.current = sonraki61

62

63

64

65

66

67 IlanPanosuUyg().run()

Burada,

116 Bölüm 12. Pencere Yöneticisi (ScreenManager)

Page 121: Kivy Mobil Programlama - Read the Docs4 Kivy Dili: kv (kv lang) 15 ... Kivy Mobil Programlama, Sürüm 0.2 ... all users” seçili iken “Next” dügmesine tıkladı˘ gınızda

BÖLÜM 13

SQLite Tarayıcı (Son Bölüm)

Uyarı: Aslında son bölüm olarak tasarladıgım bu bölümü daha önceden yazıyorum. Her ne kadar son bölüm olsada, bundan önce daha baska bölümler olacaktır. !! Bu bölüm tasarım asamasındadır ve bitmemistir. !!

Birçok promlama dilinde v birçok GUI’de SQLite için tarayıcı yazılmıstır. Buradakai amacımız yeni bir tane dahayazmak degildir. Sadece komple bir uygulamanın Kivy ie nasıl gelistirilebilecegine örnek vermek için yazılmıstır.Muhtemelen birçok böcegi (bug’ı) olacak ve hiçbir zaman üretimde kullanılabilecek tam tesekküllü bir program ola-mayacaktır.

117

Page 122: Kivy Mobil Programlama - Read the Docs4 Kivy Dili: kv (kv lang) 15 ... Kivy Mobil Programlama, Sürüm 0.2 ... all users” seçili iken “Next” dügmesine tıkladı˘ gınızda

Kivy Mobil Programlama, Sürüm 0.2

118 Bölüm 13. SQLite Tarayıcı (Son Bölüm)

Page 123: Kivy Mobil Programlama - Read the Docs4 Kivy Dili: kv (kv lang) 15 ... Kivy Mobil Programlama, Sürüm 0.2 ... all users” seçili iken “Next” dügmesine tıkladı˘ gınızda

BÖLÜM 14

Dizinler ve Tablolar

• genindex

• search

119

Page 124: Kivy Mobil Programlama - Read the Docs4 Kivy Dili: kv (kv lang) 15 ... Kivy Mobil Programlama, Sürüm 0.2 ... all users” seçili iken “Next” dügmesine tıkladı˘ gınızda

Kivy Mobil Programlama, Sürüm 0.2

120 Bölüm 14. Dizinler ve Tablolar

Page 125: Kivy Mobil Programlama - Read the Docs4 Kivy Dili: kv (kv lang) 15 ... Kivy Mobil Programlama, Sürüm 0.2 ... all users” seçili iken “Next” dügmesine tıkladı˘ gınızda

Dizin

Symbolsönceki eylem, 92Isaret Dili, 29

Aaçılır kutu, 85Agaç Görünümü, 105ActionBar, 92ActionButton, 95ActionGroup, 101ActionPrevious, 92ActionSeparator, 100ActionView, 92add_node, 110allow_empty_selection, 77allow_stretch, 64Ana Pencere, 7ana sınıf, 7app_icon, 94arg_converter, 75argüman çevirici, 75arka plan rengi, 47atlıkarınca, 59atlas, 94auto_dismiss, 31ayıraç, 100

Bbackground_color, 47Box Layout, 16BoxLayout, 10build(), 7Buildozer, 49

Ccarousel, 59clear_widgets, 63Clock, 67cls, 73

Config, 46content, 106current, 114

Ddügüm, 110Dügme, 9data, 73default panel, 106default_tab, 106default_tab_content, 106default_tab_text, 106deselected_color, 76direction, 60dismiss, 31do_default_tab, 106DropDown, 85

Een-boy oranı, 64etiket, 7etkin, 66event, 27exit_on_escape, 46eylem çubugu, 92eylem dügmesi, 95eylem görünümü, 92

FFileChooserListView, 38filters, 38font_size, 69

Ggenisletmek, 64Grafik Parçacıgı, 8Grid Layout, 17GridLayout, 10gruplamak, 101

121

Page 126: Kivy Mobil Programlama - Read the Docs4 Kivy Dili: kv (kv lang) 15 ... Kivy Mobil Programlama, Sürüm 0.2 ... all users” seçili iken “Next” dügmesine tıkladı˘ gınızda

Kivy Mobil Programlama, Sürüm 0.2

Hhide_root, 111

Iicon, 8Image, 61item_strings, 71iterate_all_nodes(), 111Izgara Pencere Düzeni, 9, 17

Kkeep_ratio, 64Kivy Dili, 15Kivy Launcher, 21kronometre, 69Kutu Pencere Düzeni, 10, 16kv lang, 15

LLabel, 7ListAdapter, 75ListItemButton, 75ListView, 71load_next, 67load_previous‘, 67loop, 67

Mmarkup, 29Metin Kutusu, 9mode, 101multiline, 36multiselect, 40, 64

Nnode, 110

Oolay, 27on_press, 28on_release, 85on_selection, 38on_selection_change, 78on_touch_down, 31

PParçacık Boyutları, 18pasiflestirmek, 66password, 20Pencere Yöneticisi, 113popup, 31Popup Pencere, 31pos_hint, 93

Rrenk, 47resim, 61RGB, 47

Sschedule_interval, 67Screen(), 114ScreenManager, 113Sekmeli Panel, 105select_node, 111selected_color, 76selected_node(), 111selection, 78selection_mode, 78SimpleListAdapter, 72size, 32size_hint, 18, 33source, 61SqLite, 89stacked widget, 113stop(), 48

TTabbedPanel, 105TabbedPanelHeader(), 106TextInput, 9timer, 66title, 8TreeView, 105

Uunschedule, 67

WWidget, 9with_previous, 96

Yyıgın, 113

Zzamanlayıcı, 66

122 Dizin