5. Pygtk’de Pencere Araçları (2. Bölüm)

Pygtk’de şimdiye kadar pencere araçları içinde gtk.Label() ve gtk.Button()’u gördük. Pygtk’de pencere araçlarından önce öğrenmemiz gereken konular olduğu için, pencere araçlarını incelemeye ara verip araya başka konular yerleştirmiştik.

Daha önce de dediğimiz gibi, Pygtk pencere araçları bakımından oldukça zengin bir arayüz takımıdır. Bu bölümde, Pygtk’deki pencere araçlarını incelemeye devam edeceğiz.

5.1. “Entry” Pencere Aracı

“Entry” pencere aracı, kullanıcıların veri girmesini sağlayan bir alandır. Bu pencere aracı dikdörtgen bir kutu şeklindedir. Python’da komut satırından çalışan programlar yazarken nasıl raw_input() ve input() fonksiyonlarından yararlanıyorsak, Pygtk’de de kullanıcıdan veri alabilmek için sıklıkla “Entry” pencere aracından faydalanacağız.

Pygtk’de Entry pencere aracı şöyle oluşturulur:

entry = gtk.Entry()

İsterseniz bunu bir de bağlamında görelim:

import pygtk
pygtk.require20()
import gtk

class Uygulama(object):
    def __init__(self):
        self.pencere = gtk.Window(gtk.WINDOW_TOPLEVEL)
        self.pencere.set_border_width(10)
        self.pencere.connect("delete_event", gtk.main_quit)

        self.entry = gtk.Entry()

        self.pencere.add(self.entry)
        self.pencere.show_all()

    def main(self):
        gtk.main()

uyg = Uygulama()
uyg.main()

Gördüğünüz gibi, Entry() pencere aracını oluşturmak öteki pencere araçlarını oluşturmaktan hiç farklı değil. Bu kodlarda, ana pencere üzerinde tek bir pencere aracı olduğu için, bu pencere aracını (yani Entry’yi) doğrudan pencerenin kendisine ekledik. Ama uygulamada Entry aracını doğrudan ana pencere üzerine eklemeyeceğiz. Çünkü muhtemelen pencere üzerinde Entry ile birlikte başka pencere araçları da olacak. O yüzden daha önceki bölümlerde öğrendiğimiz konumlandırma araçlarını (gtk.Table, gtk.VBox, gtk.HBox gibi...) kullanmamız gerekecek.

Entry() pencere aracı, kullanıcının tek satırlık bir veri girmesine müsaade eder. Eğer kullanıcının girdiği veri kutunun uzunluğunu aşıyorsa ilk yazılanlar sola doğru kayacaktır. Entry() pencere aracı üzerinde farenin sağ tuşu da otomatik olarak çalışır. Dolayısıyla herhangi bir şey yapmamıza gerek kalmadan, “kes, kopyala, yapıştır ve sil” gibi özellikler emrimize amade olacaktır...

İsterseniz Entry() pencere aracının da kullanıldığı basit bir arayüz tasarlayarak kendi kendimize pratik yapalım:

#-*-coding:utf-8-*

import pygtk
pygtk.require20()
import gtk

class Uygulama(object):
    def __init__(self):
        self.pencere = gtk.Window(gtk.WINDOW_TOPLEVEL)
        self.pencere.set_border_width(10)
        self.pencere.set_position(gtk.WIN_POS_CENTER)
        self.pencere.connect("delete_event", gtk.main_quit)

        self.kull = gtk.Label("K. Adı: ")
        self.paro = gtk.Label("Parola: ")
        self.kentry = gtk.Entry()
        self.pentry = gtk.Entry()

        self.tablo = gtk.Table(4, 4)
        self.tablo.attach(self.kull, 0, 1, 0, 1)
        self.tablo.attach(self.paro, 0, 1, 1, 2)
        self.tablo.attach(self.kentry, 1, 2, 0, 1)
        self.tablo.attach(self.pentry, 1, 2, 1, 2)

        self.pencere.add(self.tablo)

        self.kutu = gtk.HButtonBox()
        self.kutu.set_border_width(10)

        self.tablo.attach(self.kutu, 0, 2, 2, 3)

        self.btn = gtk.Button("Tamam")
        self.kutu.pack_start(self.btn)

        self.pencere.show_all()

    def main(self):
        gtk.main()

uyg = Uygulama()
uyg.main()

Burada “gtk.Table()” ve gtk.HButtonBox()” araçlarını kullanarak, ana penceremiz üzerine beş farklı pencere aracı yerleştirdik. Pencere araçlarını içinde barındıran haznelerin yerleşimine özellikle dikkat edin. Bildiğiniz gibi, ana pencere üzerine yalnızca tek bir pencere aracı ekleyebiliyoruz. Bu yüzden ana pencere üzerine “Table()” pencere aracını yerleştirdik. Table()’nin üzerine ise “HButtonBox()” haznesini koyduk.

Elbette yukarıdaki örneği farklı araçları kullanarak ve farklı şekillerde de tasarlayabilirsiniz. Örneğin sadece Table() aracını kullanarak dahi yukarıdaki arayüzü elde edebilirsiniz:

#-*-coding:utf-8-*-

import pygtk
pygtk.require20()
import gtk

class Uygulama(object):
    def __init__(self):
        self.pencere = gtk.Window(gtk.WINDOW_TOPLEVEL)
        self.pencere.set_border_width(10)
        self.pencere.set_position(gtk.WIN_POS_CENTER)
        self.pencere.connect("delete_event", gtk.main_quit)

        self.kull = gtk.Label("K. Adı: ")
        self.paro = gtk.Label("Parola: ")
        self.kentry = gtk.Entry()
        self.pentry = gtk.Entry()
        self.btn = gtk.Button("Tamam")

        self.tablo = gtk.Table(4, 4)

        #Burada "Tamam" düğmesinin denk geldiği satırı
        #öteki satırlardan biraz ayırıyoruz.
        self.tablo.set_row_spacing(1, 10)

        self.tablo.attach(self.kull, 0, 1, 0, 1)
        self.tablo.attach(self.paro, 0, 1, 1, 2)
        self.tablo.attach(self.kentry, 1, 2, 0, 1)
        self.tablo.attach(self.pentry, 1, 2, 1, 2)

        #Burada ise "Tamam" düğmesinin bütün sütunu kaplamaması için
        #gtk.SHRINK parametresinden yararlanıyoruz.
        self.tablo.attach(self.btn, 1, 2, 2, 3, gtk.SHRINK)

        self.pencere.add(self.tablo)

        self.pencere.show_all()

    def main(self):
        gtk.main()

uyg = Uygulama()
uyg.main()

Siz de bambaşka yöntemler kullanarak bu beş pencere aracını arayüz üzerine yerleştirebilirsiniz... Farklı yöntemler arasında size en kolay geleni benimsemekte özgürsünüz...

5.1.1. “Entry” Pencere Aracından Veri Almak

Entry() pencere aracının ne olduğunu ve ne işe yaradığını anlatırken, bu pencere aracını kullanıcıdan veri almak için kullanabileceğimizi söylemiştik. Kullanıcı, kendisinden istediğimiz verileri Entry() ile oluşturduğumuz kutuların içine yazıyor. Burada soru şu: Kullanıcı verileri kutulara giriyor girmesine, ama biz girilen bu bilgileri nasıl alıp kullanacağız? İşte bu bölümde bu sorunun cevabını bulmaya çalışacağız.

Pygtk’de, Entry() aracına kullanıcı tarafından girilen verileri alabilmek için “get_text()” adlı metottan yararlanacağız. Ufak bir örnekle başlayalım:

#-*-coding:utf-8-*-

import pygtk
pygtk.require20()
import gtk

class Arayuz(object):
    def __init__(self):
        self.pencere = gtk.Window(gtk.WINDOW_TOPLEVEL)
        self.pencere.set_border_width(20)
        self.pencere.set_position(gtk.WIN_POS_CENTER)
        self.pencere.connect("delete_event", gtk.main_quit)

        self.giris = gtk.Entry()
        self.dgm = gtk.Button("Göster")
        self.dgm.connect("clicked", self.goster)

        self.hbox = gtk.HBox()
        self.pencere.add(self.hbox)
        self.hbox.pack_start(self.giris)
        self.hbox.pack_start(self.dgm)

        self.pencere.show_all()

    def goster(self, penar):
        self.veri = self.giris.get_text()
        print self.veri

    def main(self):
        gtk.main()

gui = Arayuz()
gui.main()

Bu uygulamada, Entry() pencere aracına yazdığımız herhangi bir veri, “Göster” adlı düğmeye basılarak komut satırında gösterilebiliyor... Burada Entry() aracındaki veriyi almamızı sağlayan, get_text() adlı metottur. Elbette bu metodu çok daha karmaşık işler yapmak için de kullanabilirsiniz. Mesela elimizi alıştırmak için, bir sayının karekökünü hesaplayan bir uygulama yazmayı deneyelim:

#-*-coding:utf-8-*-

import pygtk
pygtk.require20()
import gtk
from math import sqrt

class Arayuz(object):
    def __init__(self):
        self.pencere = gtk.Window(gtk.WINDOW_TOPLEVEL)
        self.pencere.set_border_width(20)
        self.pencere.set_position(gtk.WIN_POS_CENTER)
        self.pencere.connect("delete_event", gtk.main_quit)

        self.giris = gtk.Entry()
        self.hesapla = gtk.Button("k.kök hesapla")
        self.hesapla.connect("clicked", self.Karekok)
        self.etiket = gtk.Label("Karekök: ")
        self.s_etiket = gtk.Label("0")

        self.tablo= gtk.Table(2, 2, homogeneous=False)
        self.tablo.set_row_spacings(10)
        self.tablo.set_col_spacings(10)
        self.pencere.add(self.tablo)

        self.tablo.attach(self.giris, 0, 1, 0, 1)
        self.tablo.attach(self.hesapla, 1, 2, 0, 1)
        self.tablo.attach(self.etiket, 0, 1, 1, 2)
        self.tablo.attach(self.s_etiket, 1, 2, 1, 2)

        self.pencere.show_all()

    def Karekok(self, penar):
        try:
            self.entry = int(self.giris.get_text())
        except ValueError:
            pass

        self.karekok = sqrt(self.entry)
        self.s_etiket.set_label(str(self.karekok))

    def main(self):
        gtk.main()

gui = Arayuz()
gui.main()

Burada kutucuğa girilen sayıların karekökünü hesaplayan bir uygulama yazdık... Bu kodlar içinde özellikle “Karekok” adlı fonksiyonun içindeki işlemlere dikkat ediyoruz. Burada çoğunlukla Python bilgimizden yararlandık, ama bu kodları yazarken Pygtk’nin bazı kaprislerini de göz önünde bulundurmamız gerekiyor. Örneğin set_label() metoduna vereceğimiz değer “karakter dizisi (string)” olmak zorunda olduğu için, “self.karekok” değerini str() fonksiyonu yardımıyla karakter dizisine çeviriyoruz. Ayrıca bu kodlarda “self.entry” değişkenini de int() fonksiyonu yardımıyla tamsayıya çevirdiğimize dikkat edin. Çünkü normalda Entry() aracından alınacak verinin tipi karakter dizisidir. Ama biz Entry() aracından aldığımız değerle bazı aritmetik işlemler yapacağımız için, öncelikle bu değeri tamsayıya çevirmemiz gerekiyor.

Bu kodlarda, dikkat ederseniz, tek bir Table() aracı kullanarak bütün pencere araçlarımızı ana pencere üzerine yerleştirebildik. Özellikle attach() metodu içinde kullandığımız koordinat bilgilerini doğru bir şekilde yazmak ilk zamanlarda epey zor olabilir. Ama bu koordinat bilgilerini yazarken, Table() pencere aracını anlattığımız bölümdeki koordinat tablosunu gözünüzün önüne getirirseniz bu bilgileri girmek biraz daha kolaylaşabilir.

Bu arada, dikkat ettiyseniz, arayüz üzerindeki “karekök” ve “0” etiketleri birbirinden çok uzak duruyor. Bunların birbirine yakın durması görünüş açısından daha şık olurdu. Şimdi bu etiketleri istediğimiz şekilde nasıl hizalayacağımıza bakalım.

Pygtk’de kullandığımız etiketleri hizalamak için set_alignment() adlı bir metottan yararlanacağız. Bu metodu şu şekilde kullanıyoruz:

etiket.set_alignment(xalign, yalign)

Gördüğünüz gibi, bu metot iki farklı parametre alıyor. “xalign” parametresi etiketin soldan sağa doğru olan hizalamasını kontrol ederken, “yalign” parametresi ise aynı etiketin yukarıdan aşağıya doğru olan hizalamasını kontrol ediyor. Bu parametreler, “0.0”, “0.5” ve “1.0” değerlerini alabilir. “xalign” parametresine vereceğimiz “0.0” değeri etiketin en solda olmasını sağlar. “0.5” değeri etiketi ortalayacak, “1.0” değeri ise etiketi en sağa yaslayacaktır. Aynı şekilde “yalign” parametresine vereceğimiz “0.0” değeri etiketi en üste hizalayacak, “0.5” değeri ortalayacak, “1.0” değeri ise en alta hizalayacaktır... (Aslında set_alignment() metodu içinde “0.0” ile “1.0” arasındaki bütün değerleri kullanabilirsiniz. Dolayısıyla hizalama konusunda ince ayara ihtiyacınız olursa 0.1, 0.2, 0.4 vb. değerler vererek istediğiniz hizalamayı elde edebilirsiniz. Ancak pek çok durumda “0.0”, “0.5” ve “1.0” değerleri bizim için yeterli olacaktır.)

Gelin isterseniz set_alignment() metodunu yukarıda verdiğimiz örneğe uygulayalım:

#-*-coding:utf-8-*-

import pygtk
pygtk.require20()
import gtk
from math import sqrt

class Arayuz(object):
    def __init__(self):
        self.pencere = gtk.Window(gtk.WINDOW_TOPLEVEL)
        self.pencere.set_border_width(20)
        self.pencere.set_position(gtk.WIN_POS_CENTER)
        self.pencere.connect("delete_event", gtk.main_quit)

        self.giris = gtk.Entry()
        self.hesapla = gtk.Button("k.kök hesapla")
        self.hesapla.connect("clicked", self.Karekok)

        self.etiket = gtk.Label("Karekök: ")
        self.etiket.set_alignment(1.0, 0.5)

        self.s_etiket = gtk.Label("0")
        self.s_etiket.set_alignment(0.0, 0.5)

        self.tablo= gtk.Table(2, 2, homogeneous=False)
        self.tablo.set_row_spacings(10)
        self.tablo.set_col_spacings(10)
        self.pencere.add(self.tablo)

        self.tablo.attach(self.giris, 0, 1, 0, 1)
        self.tablo.attach(self.hesapla, 1, 2, 0, 1)
        self.tablo.attach(self.etiket, 0, 1, 1, 2)
        self.tablo.attach(self.s_etiket, 1, 2, 1, 2)

        self.pencere.show_all()

    def Karekok(self, penar):
        try:
            self.entry = int(self.giris.get_text())
        except ValueError:
            pass

        self.karekok = sqrt(self.entry)
        self.s_etiket.set_label(str(self.karekok))

    def main(self):
        gtk.main()

gui = Arayuz()
gui.main()

Burada “self.etiket”i x düzleminde en sağa (1.0), y düzleminde ise ortaya hizaladık (0.5). Aynı şekilde “self.s_etiket”i ise x düzleminde en sola (0.0), y düzleminde de ortaya hizaladık (0.5). Y düzlemindeki hizalama ilk bakışta belli olmayabilir. Ortaya çıkan pencereyi elinizle büyütüp küçültürseniz, “yalign” parametresine verilen değerin nasıl bir etki oluşturduğunu daha açık bir şekilde görebilirsiniz.

5.1.2. “Entry”ye Girilen Veriyi Görünmez Hale Getirmek

Özellikle kullanıcı adı ve parola işlemleri için hazırlayacağımız arayüzlerde güvenlik açısından parolanın gizlenmesi gerekebilir. Örneğin, kullanıcı parolasını yazarken ekranda parola yerine “*” gibi bir karakterin görünmesini isteyebiliriz... İşte bu bölüme Entry() aracına girilen verileri bu anlamda nasıl görünmez hale getirebileceğimizi tartışacağız.

Yukarıda bahsedilen işlemi gerçekleştirmek için Pygtk’te set_visibility() adlı bir metottan yararlanacağız.

Hatırlarsanız, Entry() aracını anlatmaya başladığımız ilk bölümde şöyle bir örnek vermiştik:

#-*-coding:utf-8-*

import pygtk
pygtk.require20()
import gtk

class Uygulama(object):
    def __init__(self):
        self.pencere = gtk.Window(gtk.WINDOW_TOPLEVEL)
        self.pencere.set_border_width(10)
        self.pencere.set_position(gtk.WIN_POS_CENTER)
        self.pencere.connect("delete_event", gtk.main_quit)

        self.kull = gtk.Label("K. Adı: ")
        self.paro = gtk.Label("Parola: ")
        self.kentry = gtk.Entry()
        self.pentry = gtk.Entry()

        self.tablo = gtk.Table(4, 4)
        self.tablo.attach(self.kull, 0, 1, 0, 1)
        self.tablo.attach(self.paro, 0, 1, 1, 2)
        self.tablo.attach(self.kentry, 1, 2, 0, 1)
        self.tablo.attach(self.pentry, 1, 2, 1, 2)

        self.pencere.add(self.tablo)

        self.kutu = gtk.HButtonBox()
        self.kutu.set_border_width(10)

        self.tablo.attach(self.kutu, 0, 2, 2, 3)

        self.btn = gtk.Button("Tamam")
        self.kutu.pack_start(self.btn)

        self.pencere.show_all()

    def main(self):
        gtk.main()

uyg = Uygulama()
uyg.main()

Burada kullanıcı parolasını yazarken ekranda parolanın ne olduğu görünüyor. Ancak gerçek hayatta karşılaştığımız çoğu uygulama, kullanıcının girdiği parolayı doğrudan ekrana basmaz. Onun yerine kullanıcının girdiği her karakter için bir “*” işareti yerleştirilir. Bunu nasıl yapacağımızı görelim şimdi:

#-*-coding:utf-8-*

import pygtk
pygtk.require20()
import gtk

class Uygulama(object):
    def __init__(self):
        self.pencere = gtk.Window(gtk.WINDOW_TOPLEVEL)
        self.pencere.set_border_width(10)
        self.pencere.set_position(gtk.WIN_POS_CENTER)
        self.pencere.connect("delete_event", gtk.main_quit)

        self.kull = gtk.Label("K. Adı: ")
        self.paro = gtk.Label("Parola: ")
        self.kentry = gtk.Entry()
        self.pentry = gtk.Entry()
        self.pentry.set_visibility(False)

        self.tablo = gtk.Table(4, 4)
        self.tablo.attach(self.kull, 0, 1, 0, 1)
        self.tablo.attach(self.paro, 0, 1, 1, 2)
        self.tablo.attach(self.kentry, 1, 2, 0, 1)
        self.tablo.attach(self.pentry, 1, 2, 1, 2)

        self.pencere.add(self.tablo)

        self.kutu = gtk.HButtonBox()
        self.kutu.set_border_width(10)

        self.tablo.attach(self.kutu, 0, 2, 2, 3)

        self.btn = gtk.Button("Tamam")
        self.kutu.pack_start(self.btn)

        self.pencere.show_all()

    def main(self):
        gtk.main()

uyg = Uygulama()
uyg.main()

Artık kullanıcımız parolasını yazarken parola ekranda görünmeyecek...

Gördüğünüz gibi, parola ekrana yazılırken parola yerine “*” işaretini görüyoruz. Pygtk bize bu işaretin kendisi değiştirme imkanı da sunar. Yani illa “*” işaretini kullanmak zorunda değiliz. Bunu değiştirebiliriz. Bu işlem için set_invisible_char() adlı başka bir metottan yararlanacağız:

#-*-coding:utf-8-*

import pygtk
pygtk.require20()
import gtk

class Uygulama(object):
    def __init__(self):
        self.pencere = gtk.Window(gtk.WINDOW_TOPLEVEL)
        self.pencere.set_border_width(10)
        self.pencere.set_position(gtk.WIN_POS_CENTER)
        self.pencere.connect("delete_event", gtk.main_quit)

        self.kull = gtk.Label("K. Adı: ")
        self.paro = gtk.Label("Parola: ")
        self.kentry = gtk.Entry()
        self.pentry = gtk.Entry()
        self.pentry.set_visibility(False)
        self.pentry.set_invisible_char("?")

        self.tablo = gtk.Table(4, 4)
        self.tablo.attach(self.kull, 0, 1, 0, 1)
        self.tablo.attach(self.paro, 0, 1, 1, 2)
        self.tablo.attach(self.kentry, 1, 2, 0, 1)
        self.tablo.attach(self.pentry, 1, 2, 1, 2)

        self.pencere.add(self.tablo)

        self.kutu = gtk.HButtonBox()
        self.kutu.set_border_width(10)

        self.tablo.attach(self.kutu, 0, 2, 2, 3)

        self.btn = gtk.Button("Tamam")
        self.kutu.pack_start(self.btn)

        self.pencere.show_all()

    def main(self):
        gtk.main()

uyg = Uygulama()
uyg.main()

Böylece parola yazılırken parolanın kendisi yerine ekranda ”?” işareti görünecek...

5.1.3. “Entry”ye Girilen Verinin Azami Uzunluğunu Belirlemek

Bazı uygulamalarda Entry() aracına girilen verinin en fazla kaç karakter uzunluğunda olabileceğini önceden belirlemek gerekebilir. Örneğin bir kullanıcının girebileceği parola uzunluğunu 10 karakter ile sınırlandırmak istiyor olabilirsiniz. İşte bu işlem için Pygtk’de set_max_length() adlı bir metottan yararlanacağız.

Bir önceki bölümde verdiğimiz örnek üzerinden gidelim:

#-*-coding:utf-8-*

import pygtk
pygtk.require20()
import gtk

class Uygulama(object):
    def __init__(self):
        self.pencere = gtk.Window(gtk.WINDOW_TOPLEVEL)
        self.pencere.set_border_width(10)
        self.pencere.set_position(gtk.WIN_POS_CENTER)
        self.pencere.connect("delete_event", gtk.main_quit)

        self.kull = gtk.Label("K. Adı: ")
        self.paro = gtk.Label("Parola: ")
        self.kentry = gtk.Entry()
        self.pentry = gtk.Entry()
        self.pentry.set_visibility(False)
        self.pentry.set_max_length(10)

        self.tablo = gtk.Table(4, 4)
        self.tablo.attach(self.kull, 0, 1, 0, 1)
        self.tablo.attach(self.paro, 0, 1, 1, 2)
        self.tablo.attach(self.kentry, 1, 2, 0, 1)
        self.tablo.attach(self.pentry, 1, 2, 1, 2)

        self.pencere.add(self.tablo)

        self.kutu = gtk.HButtonBox()
        self.kutu.set_border_width(10)

        self.tablo.attach(self.kutu, 0, 2, 2, 3)

        self.btn = gtk.Button("Tamam")
        self.kutu.pack_start(self.btn)

        self.pencere.show_all()

    def main(self):
        gtk.main()

uyg = Uygulama()
uyg.main()

Burada kullanıcımız en fazla 10 karakterlik bir parola yazabilir. Kodlar arasında görünen set_max_length(10) satırı, kullanıcını 10 karakter fazlasını yazmasına engel olacaktır...

5.1.4. “Entry” Metninin Rengini Değiştirmek

Hatırlarsanız “Button” adlı pencere aracını işlerken modify_bg() adlı bir metot yardımıyla düğme renklerini değiştirebildiğimizi görmüştük. Benzer bir metodu, Entry pencere aracındaki metnin rengini değiştirmek için de kullanabiliriz. Ancak bu kez modify_bg yerine modify_text adlı bir metottan yararlanacağız. Bu metodu şu şekilde kullanıyoruz:

pencere_araci.modify_text(gtk.STATE_NORMAL, gtk.gdk.color_parse(renk))

modify_text() metodu, metin tabanlı pencere araçlarındaki metnin rengini değiştirmemize yardımcı olur.

Bu yapı size “Button” konusundan tanıdık geliyor olmalı... İsterseniz bununla ilgili küçük bir örnek yapalım:

#-*-coding: utf-8-*-

import pygtk
pygtk.require20()
import gtk

class RenkliYazi(object):
    def __init__(self):
        self.pencere = gtk.Window(gtk.WINDOW_TOPLEVEL)
        self.pencere.connect("delete_event", gtk.main_quit)

        self.hbox = gtk.HBox()
        self.pencere.add(self.hbox)

        self.tb_red = gtk.Button("kırmızı")
        self.tb_red.connect("clicked", self.renklendir, "red")

        self.entry = gtk.Entry()
        self.hbox.pack_start(self.entry)

        self.hbox.pack_start(self.tb_red)

        self.pencere.show_all()

    def renklendir(self, penar, renk):
        self.entry.modify_text(gtk.STATE_NORMAL, gtk.gdk.Color(renk))

    def main(self):
        gtk.main()

uyg = RenkliYazi()
uyg.main()

Burada eğer renklendir() fonksiyonu içindeki satır Windows’ta çalışmazsa, bunun yerine self.entry.modify_text(gtk.STATE_NORMAL, gtk.gdk.color_parse(renk)) satırını yazabileceğinizi biliyorsunuz...

5.1.5. “Entry” ile bir Örnek...

Bu bölümde Entry() pencere aracını kullanarak bir örnek uygulama yazacağız. Bu örnek uygulamayı yazarken aynı zamanda şimdiye kadar gördüğümüz konuları da tekrar etmiş olacağız.

Burada amacımız, kullanıcıdan iki adet sayı alan ve bu sayıları birbirleriyle toplayıp birbirlerinden çıkaran bir uygulama yazmak...

İlk kodlarımızı yazarak başlayalım işe:

#-*-coding:utf-8-*-

import pygtk
pygtk.require20()
import gtk

Bu kodlar uygulamamamızın demirbaşları... Bu satırların ne işe yaradığını artık adımız gibi biliyoruz.

Devam edelim...

class Uygulama(object):
    def __init__(self):
        self.pencere = gtk.Window(gtk.WINDOW_TOPLEVEL)
        self.pencere.set_position(gtk.WIN_POS_CENTER)
        self.pencere.set_border_width(20)
        self.pencere.connect("delete_event", gtk.main_quit)

Burada “Uygulama” adlı bir sınıf tanımladık. Bu sınıfımız, Python’daki yeni tip sınıfların gerektirdiği şekilde “object” sınıfından miras alıyor.

Sınıfımız içinde bir “__init__” fonksiyonu tanımlıyoruz. Arayüz oluşur oluşmaz hayata geçmesi gereken özellikleri bu __init__ fonksiyonu içine yazacağız. Burada öncelikle penceremizi oluşturduk. Ardından da “set_position()” metodunu kullanarak penceremizi ekranın en ortasında konumlandırdık. Bir sonraki satırda kullandığımız “set_border_width()” metodu ise pencere araçlarının pencere kenarına göre ne kadar uzakta yer alacağını belirliyor. “connect()” metodu ise pencere aracına bir görev atamamızı sağlıyor. Biz burada, pencerenin çarpı düğmesine basıldığında programımızın sağlıklı bir şekilde kapanabilmesini sağlamak için kullandık bu metodu...

Devam ediyoruz:

self.etk_ilk = gtk.Label("ilk sayı:")
self.etk_ilk.set_alignment(0.0, 0.5)

self.etk_iki = gtk.Label("ikinci sayı:")
self.etk_iki.set_alignment(0.0, 0.5)

self.etk_sonuc = gtk.Label("sonuç:")
self.etk_sonuc.set_alignment(0.0, 0.5)

Bu satırlarda, arayüz üzerinde yer alacak Label() araçlarını, yani etiketleri oluşturuyoruz. Arayüzümüz üzerinde “ilk sayı:”, “ikinci sayı:” ve “üçüncü sayı:” şeklinde üç adet etiket bulunacak. Bir önceki bölümde öğrendiğimiz set_alignment() metodunu kullanarak bu etiketleri sola yaslıyoruz. Bildiğiniz gibi, set_alignment() metodu “xalign” ve “yalign” olmak üzere iki farklı parametre alıyor. Bu iki parametre, “0.0”, “0.5” ve “1.0” olmak üzere üç farklı değer alabilir. Yukarıdaki kodlarda “xalign” parametrelerine “0.0” değerini vererek etiketimizin sola yaslanmasını sağladık. Eğer etiketleri ortalamak isteseydik xalign parametresine 0.5 değeri vermemiz gerekecekti. Etiketi en sağa yaslamak için ise “1.0” değerini kullanacaktık. Yazacağımız uygulamalarda “yalign” parametresine genellikle “0.5” değeri vermek mantıklı bir seçim olacaktır. Çünkü yazacağımız uygulamalarda etiketlerimizin y düzleminde (yukarıdan aşağıya doğru) genellikle orta noktaya denk gelmesini isteyeceğiz.

Şimdi yukarıda tanımladığımız her bir etiketin karşısına denk gelecek Entry() araçlarını oluşturacağız:

self.ent_ilk = gtk.Entry()
self.ent_ilk.set_alignment(0.5)

self.ent_iki = gtk.Entry()
self.ent_iki.set_alignment(0.5)

self.ent_sonuc = gtk.Entry()
self.ent_sonuc.set_alignment(0.5)

Burada yine set_alignment() metodunu kullandığımıza dikkat edin. Ancak bu metot Entry() aracıyla birlikte kullanıldığında bazı farklılıklar gösterir. set_alignment() metodunu Label() aracıyla birlikte kullanırken bu metoda iki farklı parametre veriyorduk. Ancak bu metodu Entry() aracıyla kullandığımızda tek bir parametre vermemiz yeterli olacaktır. Yukarıda Entry() aracıyla birlikte kullandığımız set_alignment() metodu, Entry() aracına yazılan verilerin kutucuğun ortasında konumlanmasını sağlıyor... Eğer bu set_alignment() satırlarını kaldıracak olursak, kullanıcının kutucuğa girdiği veriler sola yaslanacaktır. Kendi göz zevkinize göre set_alignment() satırlarını yazıp yazmamaya karar verebilirsiniz...

Bir sonraki kısımda ise toplama ve çıkarma işlemlerini yapmamızı sağlayacak düğmeleri oluşturuyoruz. “Toplama” ve “Çıkarma” işlemi için iki ayrı düğme meydana getiriyoruz:

self.btn_topla = gtk.Button("topla")
self.btn_topla.connect("clicked", self.islem, "topla")

self.btn_cikar = gtk.Button("çıkar")
self.btn_cikar.connect("clicked", self.islem, "çıkar")

Oluşturduğumuz bu düğmeleri, daha sonra tanımlayacağımız “islem” adlı bir fonksiyona bağlıyoruz. Burada, connect() metodunun üçüncü parametresini de yazdığımıza dikkat edin. “topla” ve “çıkar” olarak yazdığımız bu üçüncü parametreler sayesinde bütün işlemleri tek bir fonksiyon yardımıyla halledebileceğiz:

self.anakutu = gtk.VBox()
self.pencere.add(self.anakutu)

self.tablo = gtk.Table(3, 3)
self.anakutu.pack_start(self.tablo)

self.tablo.attach(self.etk_ilk, 0, 1, 0, 1)
self.tablo.attach(self.etk_iki, 0, 1, 1, 2)
self.tablo.attach(self.etk_sonuc, 0, 1, 2, 3)
self.tablo.attach(self.ent_ilk, 1, 2, 0, 1)
self.tablo.attach(self.ent_iki, 1, 2, 1, 2)
self.tablo.attach(self.ent_sonuc, 1, 2, 2, 3)

self.hbut = gtk.HButtonBox()
self.hbut.set_layout(gtk.BUTTONBOX_SPREAD)
self.anakutu.pack_start(self.hbut, padding=10)

self.hbut.add(self.btn_topla)
self.hbut.add(self.btn_cikar)

self.pencere.show_all()

Yukarıdaki satırlarda bir adet “VBox()”, bir adet “Table()” bir adet de “HButtonBox()” kullandık... Buradaki “VBox()” haznesi öteki araçları içine yerleştireceğimiz ana kutumuz olma görevini üstleniyor. Table() ve HButtonBox() araçlarını ana kutumuzun üzerine yerleştireceğiz. Burada hangi öğeleri hangi haznelerin içine yerleştirdiğimize dikkat edin. Table() aracı içine etiketleri (Label) ve kutucukları (Entry) yerleştiriyoruz. “topla” ve “çıkar” düğmelerini HButtonBox() içine alıyoruz. Bütün bu öğelerin hepsini ise VBox() içine koyuyoruz... Son olarak VBox()’u da ana pencere üzerine yerleştiriyoruz...

    def islem(self, penar, data):
        self.ent_sonuc.set_text("")
        self.ilk = self.ent_ilk.get_text()
        self.iki = self.ent_iki.get_text()
        try:
            if data == "topla":
                self.hesap = int(self.ilk) + int(self.iki)
            elif data == "çıkar":
                self.hesap = int(self.ilk) - int(self.iki)
            else:
                self.hesap = "İmkansız!"
        except ValueError:
            pass
        else:
            self.ent_sonuc.set_text(str(self.hesap))

    def main(self):
        gtk.main()

uyg = Uygulama()
uyg.main()

Bu bölümde ise toplama ve çıkarma işlemlerini gerçekleştiren “islem” adlı fonksiyonu yazıyoruz. Öncelikle “self.ent_sonuc.set_text(“”)” satırı ile sonuç kutusunu boşaltıyoruz. Böylece her işlemden sonra sonuç kutusu içindeki değerler temizlenmiş olacak. Aksi halde art arda gelen işlemlerin sonucu üst üste binecektir...

Sonraki iki satırda işlem kutucuklarına kullanıcı tarafından girilen verileri alıyoruz. Bunun için get_text() adlı metottan yararlanıyoruz.

Daha sonra ise bir try... except... else... bloğu oluşturuyoruz. “try...” bloğu içinde, connect() metodunun üçüncü parametresinin hangi değere sahip olduğuna bağlı olarak toplama veya çıkarma işlemi yapıyoruz. Eğer üçüncü parametre “topla” ise, yani kullanıcı toplama işlemini yapan düğmeye basmışsa, “self.hesap = int(self.ilk) + int(self.iki)” işlemi yapılacak, eğer üçüncü parametre “çıkar” ise, yani kullanıcı çıkarma işlemini yapan düğmeye basmışsa, “self.hesap = int(self.ilk) - int(self.iki)” işlemi yapılacaktır. Burada bir adet de “else” bloğu yazdık. Ama bu bloğu yazmasak da olurdu, çünkü yukarıdaki if ve elif blokları içinde belirtilen durumlar haricinde başka bir durumun gerçekleşmesi imkansızdır... Ama biz yine de işimizi sağlama almayı tercih ettik...

except... bloğunda “ValueError” hatalarını yakalıyoruz. Çünkü kullanıcı kutucuklara sayı yerine harf girerse programımız hata verecektir. Böyle bir durum olduğunda pass deyimi gereğince hiçbir şey yapmadan bir sonraki adıma geçiyoruz.

else... bloğunda ise, program hatasız bir şekilde çalışırsa ne yapılacağını belirliyoruz. Buna göre, eğer programdan herhangi bir hata alınmazsa, sonuç kutucuğu içine “hesap” değişkeninin değerini yazdırıyoruz. Burada “hesap” değişkenini str() fonksiyonu yardımıyla karakter dizisine çevirdiğimize dikkat edin. Çünkü Entry() araçlarına yalnızca karakter dizileri girebiliriz...

Sonraki kodları ise zaten tanıyorsunuz. “def main...” satırı ile main() fonksiyonunu tanımlıyoruz. Eğer bu fonksiyonu yazmak programımız çalışmayacaktır. Son olarak ise “Uygulama()” adlı sınıfımızı örnekliyoruz ve “uyg” örneği üzerinden main() fonksiyonunu çağırarak programımızı başlatıyoruz.

İsterseniz bu kodları bir bütün olarak görelim:

#-*-coding:utf-8-*-

import pygtk
pygtk.require20()
import gtk

class Uygulama(object):
    def __init__(self):
        self.pencere = gtk.Window(gtk.WINDOW_TOPLEVEL)
        self.pencere.set_position(gtk.WIN_POS_CENTER)

        self.pencere.set_border_width(20)
        self.pencere.connect("delete_event", gtk.main_quit)

        self.etk_ilk = gtk.Label("ilk sayı:")
        self.etk_ilk.set_alignment(0.0, 0.5)

        self.etk_iki = gtk.Label("ikinci sayı:")
        self.etk_iki.set_alignment(0.0, 0.5)

        self.etk_sonuc = gtk.Label("sonuç:")
        self.etk_sonuc.set_alignment(0.0, 0.5)

        self.ent_ilk = gtk.Entry()
        self.ent_ilk.set_alignment(0.5)

        self.ent_iki = gtk.Entry()
        self.ent_iki.set_alignment(0.5)

        self.ent_sonuc = gtk.Entry()
        self.ent_sonuc.set_alignment(0.5)

        self.btn_topla = gtk.Button("topla")
        self.btn_topla.connect("clicked", self.islem, "topla")

        self.btn_cikar = gtk.Button("çıkar")
        self.btn_cikar.connect("clicked", self.islem, "çıkar")

        self.anakutu = gtk.VBox()
        self.pencere.add(self.anakutu)

        self.tablo = gtk.Table(3, 3)
        self.anakutu.pack_start(self.tablo)

        self.tablo.attach(self.etk_ilk, 0, 1, 0, 1)
        self.tablo.attach(self.etk_iki, 0, 1, 1, 2)
        self.tablo.attach(self.etk_sonuc, 0, 1, 2, 3)
        self.tablo.attach(self.ent_ilk, 1, 2, 0, 1)
        self.tablo.attach(self.ent_iki, 1, 2, 1, 2)
        self.tablo.attach(self.ent_sonuc, 1, 2, 2, 3)

        self.hbut = gtk.HButtonBox()
        self.hbut.set_layout(gtk.BUTTONBOX_SPREAD)
        self.anakutu.pack_start(self.hbut, padding=10)

        self.hbut.add(self.btn_topla)
        self.hbut.add(self.btn_cikar)

        self.pencere.show_all()

    def islem(self, penar, data):
        self.ent_sonuc.set_text("")
        self.ilk = self.ent_ilk.get_text()
        self.iki = self.ent_iki.get_text()
        try:
            if data == "topla":
                self.hesap = int(self.ilk) + int(self.iki)
            elif data == "çıkar":
                self.hesap = int(self.ilk) - int(self.iki)
            else:
                self.hesap = "İmkansız!"
        except ValueError:
            pass
        else:
            self.ent_sonuc.set_text(str(self.hesap))


    def main(self):
        gtk.main()

uyg = Uygulama()
uyg.main()

Bu arada, gördüğünüz gibi, klavye üzerindeki pek çok kısayol tuşu, yazdığımız uygulama üzerinde otomatik olarak çalışıyor. Örneğin, klavyedeki sekme (tab) tuşuna basarak pencere araçları üzerinde hareket edebiliyoruz. Aynı şekilde klavye üzerindeki ok tuşları da işlevli durumda... Örneğin “topla” düğmesi seçiliyken enter tuşuna basarsak birinci ve ikinci kutudaki değerler toplanacak; “çıkar” düğmesi seçiliyken enter tuşuna basarsak da birinci ve ikinci kutudaki değerler birbirinden çıkarılacaktır...

5.2. “ToggleButton” Pencere Aracı

Bu pencere aracı, daha önce gördüğümüz “Button” adlı pencere aracına çok benzer. Ama ToggleButton ile Button arasında önemli farklar bulunur. “Toggle Button” bir nevi “açma-kapama düğmesi”dir. ToggleButton’lar “açık” ve “kapalı” olmak üzere iki farklı konumda bulunabilir. “Button” adlı düğmelerin ise böyle bir özelliği yoktur.

Pygtk’de bir ToggleButton oluşturmak için şöyle bir yapı kullanıyoruz:

tb = gtk.ToggleButton("düğme adı")

ToggleButton’u oluşturduktan sonra bu düğmeye bir kez bastığınızda düğmenin basılı kaldığını, ikinci kez bastığınızda ise düğmenin eski haline döndüğünü göreceksiniz. Bu etkiyi birden fazla ToggleButton oluşturarak daha net bir şekilde görebilirsiniz. Dilerseniz ToggleButton ile ilgili küçük bir örnek yapalım:

#-*-coding:utf-8-*-

import pygtk
pygtk.require20()
import gtk

class ToggleButton(object):
    def __init__(self):
        self.pencere = gtk.Window(gtk.WINDOW_TOPLEVEL)
        self.pencere.set_border_width(30)
        self.pencere.connect("delete_event", gtk.main_quit)

        self.vbox = gtk.VBox(True, 0)
        self.vbox.set_spacing(10) #bu komutla satır aralıklarını ayarlıyoruz.
        self.pencere.add(self.vbox)

        #şimdi beş adet ToggleButton oluşturacağız...
        for i in range(5):
            self.tb = gtk.ToggleButton("düğme%s"%i)
            self.vbox.pack_start(self.tb)

        self.pencere.show_all()

    def main(self):
        gtk.main()

ackapa = ToggleButton()
ackapa.main()

Gördüğünüz gibi, ToggleButton oluşturmak Button oluşturmaktan çok farklı değil. Şimdi gelelim bu ToggleButton adlı pencere aracının özelliklerine...

5.2.1. ToggleButton’un Durumunu Öğrenmek

Pygtk’de ToggleButton adlı pencere aracının “açık” ve “kapalı” olmak üzere iki farklı konumda bulunduğunu söylemiştik. Bir ToggleButton’un basılı konumu “True”, basılı olmayan konumu ise “False” değerine sahiptir. ToggleButton’un basılı durumda olup olmadığı bilgisi get_active() adlı bir metot yardımıyla alabiliriz:

#-*-coding:utf-8-*-

import pygtk
pygtk.require20()
import gtk

class ToggleButton(object):
    def __init__(self):
        self.pencere = gtk.Window(gtk.WINDOW_TOPLEVEL)
        self.pencere.set_border_width(30)
        self.pencere.connect("delete_event", gtk.main_quit)

        self.vbox = gtk.VBox(True, 0)
        self.vbox.set_spacing(10)
        self.pencere.add(self.vbox)

        for i in range(5):
            self.tb = gtk.ToggleButton("düğme%s"%i)

            #burada "self.tb.get_label()" fonksiyonu bize düğmenin adını veriyor
            #Eğer isterseniz "clicked" yerine "toggled" sinyalini de kullanabilirsiniz.
            self.tb.connect("clicked", self.fonk, self.tb.get_label())
            self.vbox.pack_start(self.tb)

        self.pencere.show_all()

    def fonk(self, penar, data):
        #"get_active()" metodunu nasıl kullandığımıza dikkat edin.
        #Bu metot bize ToggleButton'un basılı olup olmadığı
        #bilgisini veriyor.
        print "%s: %s"%(data, penar.get_active())

    def main(self):
        gtk.main()

tb = ToggleButton()
tb.main()

Bu kodları çalıştırdıktan sonra arayüz üzerindeki düğmelere bastığımızda hem düğmenin adı hem de düğmenin basılı olup olmadığı bilgisi komut satırında görüntülenecektir. “True” değeri düğmenin basılı olduğunu, “False” değeri ise düğmenin basılı olmadığını gösterir. Eğer “True” ve “False” değerleri yerine daha anlamlı kelimeler kullanmak isterseniz fonk() adlı fonksiyonu şöyle yazabilirsiniz:

def fonk(self, penar, data):
    print "%s %s"%(data, ("kapalı", "açık")[penar.get_active()])

Böylece düğmeye ilk basışta komut satırında “açık” çıktısı, ikinci basışta ise “kapalı” çıktısı görüntülenecektir... “Kapalı” ve “açık” kelimeleri yerine istediğiniz kelimeleri koymakta özgürsünüz...

Dilerseniz ToggleButton’un kullanımını biraz daha netleştirmek için ufak bir örnek verelim:

#-*-coding:utf-8-*-

import pygtk
pygtk.require20()
import gtk

class ToggleButton(object):
    def __init__(self):
        self.pencere = gtk.Window(gtk.WINDOW_TOPLEVEL)
        self.pencere.set_border_width(30)
        self.pencere.connect("delete_event", gtk.main_quit)

        self.tablo = gtk.Table(4, 2, True)
        self.tablo.set_row_spacings(5)
        self.pencere.add(self.tablo)

        #beş tane farklı ToggleButton oluşturuyoruz...
        for i in range(5):
            self.btn = gtk.ToggleButton("düğme%s"%i)

            self.etk = gtk.Label()
            self.etk.set_text("")

            #oluşturduğumuz düğme ve etiketleri tabloya yerleştiriyoruz.
            self.tablo.attach(self.btn, 0, 1, i, i+1)
            self.tablo.attach(self.etk, 1, 2, i, i+1)

            self.btn.connect("clicked", self.fonk, self.etk)

        self.pencere.show_all()

    #düğmelere her basışta düğme durumunun etikete yazdırılması için
    #"fonk()" adlı bir fonksiyon yazıyoruz...
    def fonk(self, dugme, etiket):
        self.durum = ("kapalı", "açık")[dugme.get_active()]
        etiket.set_text(str(self.durum))

    def main(self):
        gtk.main()

tb = ToggleButton()
tb.main()

Burada ToggleButton’un açık mı yoksa kapalı mı olduğu bilgisi komut satırına değil, arayüz üzerindeki etiketlere yazdırılıyor...

5.2.2. ToggleButton’un Açılış Değerini Belirlemek

Normal şartlar altında bir ToggleButton ilk oluşturulduğunda kapalıdır. Eğer oluşturduğunuz ToggleButton’un ilk açıldığında basılı/açık olmasını isterseniz set_active() adlı metottan yararlanabilirsiniz:

tb = gtk.ToggleButton("isim")
tb.set_active(True)

Böylece ToggleButton ilk oluştuğunda “True” değerine sahip olacaktır.

5.3. “CheckButton” Pencere Aracı

“CheckButton” bildiğimiz onay kutusudur... Pygtk’de oluşturduğumuz arayüzlere “CheckButton” eklemek için şu yolu takip ediyoruz:

onay_kutusu = gtk.CheckButton("isim")

Yukarıda “ToggleButton” için verdiğimiz örneği aynen “CheckButton” için de verebiliriz. Tek fark, yukarıda “ToggleButton” geçen yerlere “CheckButton” yazıyoruz:

#-*-coding:utf-8-*-

import pygtk
pygtk.require20()
import gtk

class CheckButton(object):
    def __init__(self):
        self.pencere = gtk.Window(gtk.WINDOW_TOPLEVEL)
        self.pencere.set_border_width(30)
        self.pencere.connect("delete_event", gtk.main_quit)

        self.tablo = gtk.Table(4, 2, True)
        self.tablo.set_row_spacings(5)
        self.pencere.add(self.tablo)

        #beş tane farklı CheckButton oluşturuyoruz...
        for i in range(5):
            self.btn = gtk.CheckButton("düğme%s"%i)

            self.etk = gtk.Label()
            self.etk.set_text("")

            #oluşturduğumuz düğme ve etiketleri tabloya yerleştiriyoruz.
            self.tablo.attach(self.btn, 0, 1, i, i+1)
            self.tablo.attach(self.etk, 1, 2, i, i+1)

            self.btn.connect("clicked", self.fonk, self.etk)

        self.pencere.show_all()

    #düğmelere her basışta düğme durumunun etikete yazdırılması için
    #"fonk()" adlı bir fonksiyon yazıyoruz...
    def fonk(self, dugme, etiket):
        self.durum = ("seçili değil", "seçili")[dugme.get_active()]
        etiket.set_text(str(self.durum))

    def main(self):
        gtk.main()

tb = CheckButton()
tb.main()

5.4. “RadioButton” Pencere Aracı

ToggleButton ve CheckButton’a çok benzeyen başka bir pencere aracı da “RadioButton”dur. Bu pencere aracını şu şekilde oluşturuyoruz:

rb = gtk.Radiobutton(grup, "isim")

Bu formülde, öteki pencere araçlarında olmayan bir parametre göze çarpıyor. Pygtk’de bir “RadioButton” pencere aracı oluşturabilmek için formülde görünen bu “grup” adlı parametreyi mutlaka belirtmemiz gerekir. Eğer bu parametreyi belirtmeden şöyle bir örnek kod yazacak olursak Python bize bir hata mesajı gösterecektir:

#-*-coding:utf-8-*-
import pygtk
pygtk.require20()
import gtk

class RadioButton(object):
    def __init__(self):
        self.pencere = gtk.Window(gtk.WINDOW_TOPLEVEL)
        self.pencere.connect("delete_event", gtk.main_quit)

        self.rb = gtk.RadioButton("rb1")
        self.pencere.add(self.rb)
        self.pencere.show_all()

    def main(self):
        gtk.main()

rb = RadioButton()
rb.main()

Bu kodları çalıştırdığımızda şu hata mesajını alırız:

TypeError: first argument must be a GtkRadioButton or None

Pygtk’de bir RadioButton oluşturacağımız zaman, bu pencere aracını mutlaka başka bir veya daha fazla RadioButton grubuna dahil etmemiz gerekir. Peki ya elimizde sadece tek bir RadioButton varsa ne olacak? Aslında mantık olarak arayüz üzerinde tek bir RadioButton kullanmak son derece anlamsızdır. Neticede arayüz üzerinde birden fazla RadioButton olmalı, ki kullanıcı bu RadioButton’lar arasında seçim yapabilsin...

Şimdi isterseniz daha mantıklı bir örnek verelim:

#-*-coding:utf-8-*-
import pygtk
pygtk.require20()
import gtk

class RadioButton(object):
    def __init__(self):
        self.pencere = gtk.Window(gtk.WINDOW_TOPLEVEL)
        self.pencere.set_border_width(10)
        self.pencere.connect("delete_event", gtk.main_quit)

        self.vbox = gtk.VBox()

        self.etiket = gtk.Label("Python'un Hangi Sürümünü Kullanıyorsunuz?")

        self.rb1 = gtk.RadioButton(None, "Python 2.5")
        self.rb2 = gtk.RadioButton(self.rb1, "Python 2.6")
        self.rb3 = gtk.RadioButton(self.rb1, "Python 3.0")
        self.rb4 = gtk.RadioButton(self.rb1, "Python 3.1")

        self.vbox.pack_start(self.etiket, True, True, 10)
        self.vbox.pack_start(self.rb1)
        self.vbox.pack_start(self.rb2)
        self.vbox.pack_start(self.rb3)
        self.vbox.pack_start(self.rb4)

        self.pencere.add(self.vbox)

        self.pencere.show_all()

    def main(self):
        gtk.main()

rb = RadioButton()
rb.main()

Burada, “self.rb1” adlı ilk RadioButton aracı herhangi bir gruba üye olamayacağı için, bunun “grup” parametresine “None” değeri verdik. Ondan sonra oluşturduğumuz RadioButton’ları ise “self.rb1” ile grupladık. Böylece bütün RadioButton’lar birbirlerinden haberdar olmuş oldu. İsterseniz oluşturduğumuz dört RadioButton’a da ilk parametre olarak “None” değerini vermeyi deneyin. Bu şekilde RadioButton’ların birbirinden habersiz olduğunu göreceksiniz...

Hangi RadioButton’un seçili olduğunu, hangisini seçili olmadığını öğrenmek için de get_active() adlı metodu kullanabilirsiniz. Mesela yukarıdaki örneği şöyle yazabilirsiniz:

#-*-coding:utf-8-*-
import pygtk
pygtk.require20()
import gtk

class RadioButton(object):
    def __init__(self):
        self.pencere = gtk.Window(gtk.WINDOW_TOPLEVEL)
        self.pencere.set_border_width(10)
        self.pencere.connect("delete_event", gtk.main_quit)

        self.vbox = gtk.VBox()

        self.etiket = gtk.Label("Python'un Hangi Sürümünü Kullanıyorsunuz?")

        self.rb1 = gtk.RadioButton(None, "Python 2.5")
        self.rb1.connect("clicked", self.fonk)

        self.rb2 = gtk.RadioButton(self.rb1, "Python 2.6")
        self.rb2.connect("clicked", self.fonk)

        self.rb3 = gtk.RadioButton(self.rb1, "Python 3.0")
        self.rb3.connect("clicked", self.fonk)

        self.rb4 = gtk.RadioButton(self.rb1, "Python 3.1")
        self.rb4.connect("clicked", self.fonk)

        self.vbox.pack_start(self.etiket, True, True, 10)
        self.vbox.pack_start(self.rb1)
        self.vbox.pack_start(self.rb2)
        self.vbox.pack_start(self.rb3)
        self.vbox.pack_start(self.rb4)

        self.pencere.add(self.vbox)

        self.pencere.show_all()

    def fonk(self, penar):
        durum = (u"seçili değil", u"seçili")[penar.get_active()]
        print "%s %s" % (penar.get_label(), durum)

    def main(self):
        gtk.main()

rb = RadioButton()
rb.main()

fonk() adlı fonksiyon içindeki yapıyı, daha önce gördüğümüz CheckButton ve ToggleButton adlı pencere araçlarından da hatırlıyor olmalısınız.

RadioButton’lardaki bu “grup” parametresi, farklı RadioButton gruplarıyla çalışmak istediğinizde işinize çok yarayacaktır. Mesela buna şöyle bir örnek verebiliriz:

#-*-coding:utf-8-*-
import pygtk
pygtk.require20()
import gtk

class RadioButton(object):
    def __init__(self):
        self.pencere = gtk.Window(gtk.WINDOW_TOPLEVEL)
        self.pencere.set_border_width(10)
        self.pencere.connect("delete_event", gtk.main_quit)

        self.vbox = gtk.VBox()

        self.etiket_py = gtk.Label("Python'un Hangi Sürümünü Kullanıyorsunuz?")

        self.rb1_py = gtk.RadioButton(None, "Python 2.5")
        self.rb1_py.connect("clicked", self.fonk)

        self.rb2_py = gtk.RadioButton(self.rb1_py, "Python 2.6")
        self.rb2_py.connect("clicked", self.fonk)

        self.rb3_py = gtk.RadioButton(self.rb1_py, "Python 3.0")
        self.rb3_py.connect("clicked", self.fonk)

        self.rb4_py = gtk.RadioButton(self.rb1_py, "Python 3.1")
        self.rb4_py.connect("clicked", self.fonk)

        self.etiket_de = gtk.Label("Hangi Masaüstü Ortamını Kullanıyorsunuz?")

        self.rb1_de = gtk.RadioButton(None, "KDE 3.5")
        self.rb1_de.connect("clicked", self.fonk)

        self.rb2_de = gtk.RadioButton(self.rb1_de, "KDE 4")
        self.rb2_de.connect("clicked", self.fonk)

        self.rb3_de = gtk.RadioButton(self.rb1_de, "GNOME")
        self.rb3_de.connect("clicked", self.fonk)

        self.rb4_de = gtk.RadioButton(self.rb1_de, "XFCE")
        self.rb4_de.connect("clicked", self.fonk)

        self.vbox.pack_start(self.etiket_py, True, True, 10)
        self.vbox.pack_start(self.rb1_py)
        self.vbox.pack_start(self.rb2_py)
        self.vbox.pack_start(self.rb3_py)
        self.vbox.pack_start(self.rb4_py)

        self.vbox.pack_start(self.etiket_de, True, True, 10)
        self.vbox.pack_start(self.rb1_de)
        self.vbox.pack_start(self.rb2_de)
        self.vbox.pack_start(self.rb3_de)
        self.vbox.pack_start(self.rb4_de)

        self.pencere.add(self.vbox)

        self.pencere.show_all()

    def fonk(self, penar):
        durum = (u"seçili değil", u"seçili")[penar.get_active()]
        print "%s %s" % (penar.get_label(), durum)

    def main(self):
        gtk.main()

rb = RadioButton()
rb.main()

Burada aynı arayüz üzerinde iki farklı RadioButton grubu kullanıyoruz. İlk grubumuz Python sorusuyla ilgili. İkinci grup ise Masaüstü sorusuyla... RadioButton aracındaki “grup” parametresi sayesinde iki farklı grup içinde yer alan pencere araçlarının birbiriyle karışmasını engelliyoruz.