3. Pygtk’de Pencere Araçları (1. Bölüm)¶
Bu bölümde Pygtk’deki pencere araçlarını anlatmaya başlayacağız. Peki pencere aracı nedir? Hemen söyleyelim:
Bir programın arayüzü üzerinde görünen, düğme, etiket, kutucuk, menü vb. araçlara, “pencere aracı” (Window Gadget – Widget) adı verilir.
Pygtk; pencere araçlarının sayısı bakımından oldukça zengin bir arayüz takımıdır. Bir programda ihtiyaç duyabileceğimiz bütün pencere araçlarını Pygtk’de bulabiliriz...
Bu bölümde inceleyeceğimiz ilk pencere aracı “Label” olacak. O halde yola koyulalım...
3.1. “Label” Pencere Aracı¶
“Label”, kelime olarak “etiket” anlamına gelir. Oluşturduğumuz arayüz üzerinde kullanıcıya bir not veya mesaj göstermek istediğimizde “Label” adlı bu pencere aracından yararlanabiliriz. Pygtk’de bir “Label” oluşturmak istediğimizde şuna benzer bir kod yazıyoruz:
etiket = gtk.Label()
Elbette yukarıdaki satır, “Label” aracının iskeletidir yalnızca. Gerçek hayatta Label’i kullanırken, bu pencere aracına bazı başka şeyler de eklememiz gerekir. İsterseniz bu araçla ilgili basit bir örnek vererek başlayalım işe:
import pygtk
pygtk.require20()
import gtk
class Uygulama(object):
def __init__(self):
self.pencere = gtk.Window(gtk.WINDOW_TOPLEVEL)
self.pencere.connect("delete_event", self.kapat)
self.pencere.show()
self.etiket = gtk.Label("Merhaba")
self.pencere.add(self.etiket)
self.etiket.show()
def kapat(self, penar, event):
gtk.main_quit()
def main(self):
gtk.main()
uyg = Uygulama()
uyg.main()
Gördüğünüz gibi, Pygtk ile bir etiket oluşturmak hiç de zor değil. Burada gördüğünüz gibi, Pygtk’de bir etiket oluşturmak için üç aşamadan geçiyoruz:
self.etiket = gtk.Label("Merhaba")
self.pencere.add(self.etiket)
self.etiket.show()
Dilerseniz bu aşamaları tek tek inceleyelim:
Öncelikle şu kodu kullanarak bir etiket meydana getiriyoruz:
self.etiket = gtk.Label("Merhaba")
Burada etiketi oluşturan fonksiyon, “gtk.Label()”. Bu fonksiyon içinde kullandığımız karakter dizisi ise bu etiketin içeriğini gösteriyor. Biz ilk etiketimiz için “Merhaba” karakter dizisini kullandık.
Etiketimizi oluşturduktan sonra yapmamız gereken bir şey daha var. Pygtk’de pencere araçlarını görünür hale getirebilmek için bu araçları pencere üzerine “eklememiz” lazım. Dolayısıyla yukarıdaki formül aracılığıyla etiketimizi oluşturduktan sonra yapmamız gereken ilk iş bu etiketi pencereye eklemek olacaktır. Eğer etiketimizi pencereye eklemezsek, programımızı çalıştırmak istediğimizde etiketimiz ekranda görünmeyecektir.
Etiketi pencereye ekleme işlemini şu kodla yapıyoruz:
self.pencere.add(self.etiket)
Oluşturduğumuz etiketi pencereye eklemek için add() adlı bir metottan yararlandığımıza dikkat edin. “add” kelimesi Türkçe’de “eklemek” anlamına gelir. Dolayısıyla yukarıdaki satır ile “self.etiket”i, “self.pencere”ye eklemiş (add) olduk...
Artık etiketimizi ekranda gösterebiliriz:
self.etiket.show()
Yukarıdaki kodların geri kalanının ne işe yaradığını biliyorsunuz. Bunları önceki bölümlerde görmüştük.
Dikkat ederseniz, yukarıdaki kodları kullanarak oluşturduğumuz pencere yine “200x200” piksel boyutunda. Yani pencerenin kendisi, pencere üzerine yerleştirdiğimiz etiketten büyük. Aslında tahminimce siz de görüntünün böyle olmasını isteyeceksiniz... Ama eğer oluşan pencerenin etiketin kapladığı alanla sınırlı olmasını isterseniz kodlarınızı şu şekilde yazabilirsiniz:
import pygtk
pygtk.require20()
import gtk
class Uygulama(object):
def __init__(self):
self.pencere = gtk.Window(gtk.WINDOW_TOPLEVEL)
self.pencere.connect("delete_event", self.kapat)
self.etiket = gtk.Label("Merhaba")
self.pencere.add(self.etiket)
self.etiket.show()
self.pencere.show()
def kapat(self, penar, event):
gtk.main_quit()
def main(self):
gtk.main()
uyg = Uygulama()
uyg.main()
Burada yaptığımız tek değişiklik, “self.pencere.show()” satırının yerini değiştirmek oldu... Ana penceremizi etiketten sonra göstererek, penceremizin etiket boyutuyla sınırlı olmasını sağladık. Peki bu nasıl oluyor?
Pygtk ile boş bir pencere oluşturduğumuzda, oluşan boş pencerenin boyutu varsayılan olarak “200x200” pikseldir. Yukarıda verdiğimiz ilk kodlarda ana pencereyi etiketten önce gösterdiğimiz için, pencere oluştuğu sırada henüz ortada bir etiket olmadığından, oluşan pencere “200x200” piksel boyutunda oluyor. Ama ana pencereyi etiketten sonra gösterirsek, pencere oluştuğu sırada kendisinden önce oluşmuş bir etiket olacağı için, ana penceremiz etiketin sahip olduğu boyuta göre kendini ayarlıyor. Elbette önceki bölümlerde öğrendiğimiz şekilde, resize() veya get_size_request() metodunu kullanarak pencere boyutunu kendimiz de ayarlayabiliriz:
import pygtk
pygtk.require20()
import gtk
class Uygulama(object):
def __init__(self):
self.pencere = gtk.Window(gtk.WINDOW_TOPLEVEL)
self.pencere.resize(400, 400)
#dilerseniz resize() yerine set_size_request() de
#kullanabilirsiniz:
#self.pencere.set_size_request(400, 400)
self.pencere.connect("delete_event", self.kapat)
self.etiket = gtk.Label("Merhaba")
self.pencere.add(self.etiket)
self.etiket.show()
self.pencere.show()
def kapat(self, penar, event):
gtk.main_quit()
def main(self):
gtk.main()
uyg = Uygulama()
uyg.main()
Gördüğünüz gibi, self.pencere’yi kodların neresinde göstermiş olursak olalım, resize() (veya get_size_request()) metodu yardımıyla pencerenin sahip olması gereken boyutu belirlediğimiz için, penceremiz bizim istediğimiz boyutlara göre açılıyor...
Bu arada, dikkat ederseniz, yukarıdaki kodlarda herhangi bir Türkçe karakter kullanmamaya özen gösterdik. Elbette istersek Pygtk uygulamalarında Türkçe karakterleri de rahatlıkla gösterebiliriz. Ama bunun için öncelikle betiğimizin dil kodlamasını belirlememiz gerekir. Bunu nasıl yapacağımızı biliyorsunuz. Kodlarımızın en başına şu satırı ekleyeceğiz:
#-*-coding: utf-8 -*-
Dolayısıyla kodlarımızın son hali şöyle olacak:
#-*-coding: utf-8 -*-
import pygtk
pygtk.require20()
import gtk
class Uygulama(object):
def __init__(self):
self.pencere = gtk.Window(gtk.WINDOW_TOPLEVEL)
self.pencere.resize(400, 400)
self.pencere.connect("delete_event", self.kapat)
self.etiket = gtk.Label("Merhaba Türkçe karakterler: şçöğüıŞÇÖĞÜİ")
self.pencere.add(self.etiket)
self.etiket.show()
self.pencere.show()
def kapat(self, penar, event):
gtk.main_quit()
def main(self):
gtk.main()
uyg = Uygulama()
uyg.main()
Pygtk ile bir etiket oluşturmayı öğrendik. Şimdi bu etiketi nasıl düzenleyebileceğimize bakacağız. Örneğin bu etiketin yazıtipi, renk, boyut, vb. özelliklerini nasıl değiştirebileceğimizi inceleyeceğiz...
3.1.1. Etiket Metnini Değiştirmek¶
“Label” pencere aracının metnini belirledikten sonra, programın işleyişi sırasında bazı noktalarda bu metni değiştirmek gerekebilir. Bu pencere aracının metnini değiştirmek için set_text() adlı 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.resize(400, 400)
self.pencere.connect("delete_event", gtk.main_quit)
self.etiket = gtk.Label()
self.pencere.add(self.etiket)
self.etiket.show()
self.pencere.show()
self.etiket.set_text("İşlem Tamamlandı!")
def main(self):
gtk.main()
uyg = Uygulama()
uyg.main()
Gördüğünüz gibi, etiketi ilk oluşturduğumuzda bu etiket herhangi bir metin içermiyor. Etiketin metnini, set_text() adlı metottan yararlanarak, sonradan oluşturduk...
Elbette, yukarıdaki örnek pek işlevli değil... Eğer biz etiket metnini program çalıştığı sırada değiştirebilirsek tabii ki örneğimiz çok daha mantıklı olacaktır. Mesela, programımız ilk açıldığında “Lütfen bekleyiniz...” gibi bir yazı görsek... Ardından da bu yazı belli bir süre sonra “İşlem tamamlandı...” şekline dönüşse çok daha iyi bir örnek vermiş olacağız... Önce şöyle bir deneme yapalım:
#-*-coding:utf-8-*-
import pygtk
pygtk.require20()
import gtk
import time
class Uygulama(object):
def __init__(self):
self.pencere = gtk.Window(gtk.WINDOW_TOPLEVEL)
self.pencere.connect("delete_event", gtk.main_quit)
self.pencere.resize(500, 500)
self.pencere.set_title("deneme 1, 2, 3...")
self.pencere.show()
self.etiket = gtk.Label("Lütfen bekleyiniz...")
self.pencere.add(self.etiket)
self.etiket.show()
time.sleep(1)
self.etiket.set_text("İşlem tamamlandı!")
def main(self):
gtk.main()
uyg = Uygulama()
uyg.main()
Gördüğünüz gibi, bu kodlar istediğimiz işlemi yerine getiremedi. Programımız “1” saniye bekledikten sonra açıldı ve sadece “İşlem tamamlandı!” etiketini gösterdi. Halbuki bizim istediğimiz bu değil...
Pygtk’de bu tür işlemleri yapabilmek için kodlarımız arasına şu satırları eklememiz gerekir:
while gtk.events_pending():
gtk.main_iteration()
Bu kodların görevi, arayüzün güncellenmesini sağlamaktır. Eğer arayüz üzerinde gerçekleşmeyi bekleyen olaylar varsa, bu kodlar sayesinde arayüz her olaydan sonra güncellenir. Böylelikle arayüz üzerinde belli bir süre zarfında gerçekleşen farklı olaylar, arayüzün güncellenmesi sayesinde kullanıcıya gösterilebilir. İsterseniz bunu bir örnekle somutlaştırmaya çalışalım:
#-*-coding:utf-8-*-
import pygtk
pygtk.require20()
import gtk
import time
class Uygulama(object):
def __init__(self):
self.pencere = gtk.Window(gtk.WINDOW_TOPLEVEL)
self.pencere.connect("destroy", gtk.main_quit)
self.pencere.resize(300, 300)
self.pencere.set_position(gtk.WIN_POS_CENTER)
self.pencere.set_title("deneme 1, 2, 3...")
self.pencere.show()
self.etiket = gtk.Label("Lütfen bekleyiniz...")
self.pencere.add(self.etiket)
self.etiket.show()
while gtk.events_pending():
gtk.main_iteration()
time.sleep(1)
self.etiket.set_text("İşlem tamamlandı!")
def main(self):
gtk.main()
uyg = Uygulama()
uyg.main()
Bu defa, programımız istediğimiz işlemi gerçekleştirdi. Tam istediğimiz şekilde, programımız “Lütfen bekleyiniz...” etiketiyle açıldı ve “1” saniye sonra bu etiket “İşlem tamamlandı!” şekline dönüştü. Burada “while gtk.events...” kodlarının görevi, arayüzü takibe almak... Bu kodlar, arayüz üzerinde gerçekleşmeyi bekleyen herhangi bir olay olup olmadığını sürekli olarak kontrol ediyor. Bizim örneğimizde, “1” saniye sonra değişmeyi bekleyen bir etiket olduğu için, while gtk.events_pending(): gtk.main_iteration() kodları arayüzün donup kalmasını engelliyor ve tıpkı olması gerektiği gibi, “1” saniye sonra etiketi değiştiriyor...
Yukarıdakine benzer bir başka örnek daha verelim. Mesela bu kez bir “sayaç” örneği hazırlayalım. Yazacağımız programda 1’den 10’a kadar aralıksız olarak sayalım:
#-*-coding: utf-8 -*-
import pygtk
pygtk.require20()
import gtk
import time
class Uygulama(object):
def __init__(self):
self.pencere = gtk.Window(gtk.WINDOW_TOPLEVEL)
self.pencere.connect("delete_event", self.kapat)
self.etiket = gtk.Label("başlıyor...")
self.pencere.add(self.etiket)
self.pencere.show()
self.etiket.show()
for i in range(11):
while gtk.events_pending():
gtk.main_iteration()
time.sleep(1)
self.etiket.set_text("%s" %i)
def kapat(self, penar, event):
gtk.main_quit()
def main(self):
gtk.main()
uyg = Uygulama()
uyg.main()
Eğer burada “while gtk.events_pending(): gtk.main_iteration” kodlarını yazmazsak, programımızı çalıştırdığımızda arayüzümüz bir süre bekleyecek, alttan alta 10’a kadar saymayı bitirdikten sonra kendini gösterecektir...
3.1.2. Etiketlerin Rengini Değiştirmek¶
Bir “Label” aracı üzerindeki metnin rengini değiştirmek konusunda Pygtk bize çok büyük olanaklar sağlar. Metin rengini (ve metnin başka pek çok özelliğini) değiştirmek için kullanabileceğimiz, “Pango Markup Language” (Pango İşaretleme Dili) adlı ufak bir dil yapısı sunar bize Pygtk... “Pango İşaretleme Dili”, HTML’ye oldukça benzer bir dildir. Dolayısıyla temel HTML bilgisi, biraz sonra göstereceğimiz örnekleri anlamak bakımından epey yararlı olacaktır.
Bu bölümde, bir etiketteki metnin yazıtipi rengini nasıl değiştireceğimizi öğreneceğiz. İsterseniz bir önceki bölümde gördüğümüz örnek üzerinden gidelim. Örneğimiz şuydu:
#-*-coding: utf-8 -*-
import pygtk
pygtk.require20()
import gtk
import time
class Uygulama(object):
def __init__(self):
self.pencere = gtk.Window(gtk.WINDOW_TOPLEVEL)
self.pencere.connect("delete_event", self.kapat)
self.etiket = gtk.Label("başlıyor...")
self.pencere.add(self.etiket)
self.pencere.show()
self.etiket.show()
for i in range(11):
while gtk.events_pending():
gtk.main_iteration()
time.sleep(1)
self.etiket.set_text("%s" %i)
def kapat(self, penar, event):
gtk.main_quit()
def main(self):
gtk.main()
uyg = Uygulama()
uyg.main()
Şimdi burada, arayüz üzerinde tek tek görünen sayıların rengini değiştireceğiz. Normalde bu sayılar siyah renkte, ama biz bu sayıları kırmızıya döndüreceğiz:
#-*-coding: utf-8 -*-
import pygtk
pygtk.require20()
import gtk
import time
class Uygulama(object):
def __init__(self):
self.pencere = gtk.Window(gtk.WINDOW_TOPLEVEL)
self.pencere.connect("delete_event", self.kapat)
self.etiket = gtk.Label("başlıyor...")
self.pencere.add(self.etiket)
self.pencere.show()
self.etiket.show()
for i in range(11):
while gtk.events_pending():
gtk.main_iteration()
time.sleep(1)
self.etiket.set_markup("<span foreground='red'>%s</span>"%i)
def kapat(self, penar, event):
gtk.main_quit()
def main(self):
gtk.main()
uyg = Uygulama()
uyg.main()
Gördüğünüz gibi, programı çalıştırdığımızda, arayüz üzerindeki sayılar kırmızı renkte görünüyor. Burada kullandığımız kodun formülü şöyledir:
pencere_aracı.set_markup("<span foreground='renk'>metin</span>")
Bu arada, set_markup() metodunun, etiketin metnini ayarlama görevi gördüğüne de dikkat edin. Burada ayrıca set_text() gibi bir metot kullanmamıza gerek kalmadı.
İsterseniz bununla ilgili daha basit bir örnek yapalım:
import pygtk
pygtk.require20()
import gtk
class Uygulama(object):
def __init__(self):
self.pencere = gtk.Window(gtk.WINDOW_TOPLEVEL)
self.pencere.connect("delete_event", gtk.main_quit)
self.pencere.show()
self.etiket = gtk.Label("Merhaba")
self.etiket.set_markup("<span foreground='blue'>Merhaba</span>")
self.pencere.add(self.etiket)
self.etiket.show()
def main(self):
gtk.main()
uyg = Uygulama()
uyg.main()
Burada, İngilizce’deki temel renk adlarını kullanabiliyoruz. Bu renk adlarından bazılarını verelim:
red = kırmızı
blue = mavi
white = beyaz
black = siyah
green = yeşil
brown = kahverengi
orange = kavuniçi
purple = eflatun
Elbette sadece bu renklerle sınırlı değiliz. Eğer isterseniz http://html-color-codes.info/ adresini ziyaret ederek, oradaki renk paletinden bir renk seçip programınız içinde kullanabilirsiniz. O adresteki renkleri şöyle kullanıyoruz:
Renk paletinden istediğiniz bir rengin üzerine tıklayın. Aşağıda “selected color code is:” yazan kutucuktaki kodun tamamını kopyalayın ve programınız içinde ilgili yere yapıştırın. Bir örnek verelim... Diyelim ki o renk paletinden bir renk seçtik ve “#610B5E” kodunu elde ettik. Şimdi bu kodun tamamını kopyalıyoruz ve gerekli yere yapıştırıyoruz:
import pygtk
pygtk.require20()
import gtk
class Uygulama(object):
def __init__(self):
self.pencere = gtk.Window(gtk.WINDOW_TOPLEVEL)
self.pencere.connect("delete_event", gtk.main_quit)
self.pencere.show()
self.etiket = gtk.Label("Merhaba")
self.etiket.set_markup("<span foreground='#610B5E'>Merhaba</span>")
self.pencere.add(self.etiket)
self.etiket.show()
def main(self):
gtk.main()
uyg = Uygulama()
uyg.main()
Gördüğünüz gibi, seçtiğimiz renk başarıyla etiket rengi olarak ayarlandı...
Eğer etiket metnini yukarıda yaptığımız gibi üst üste iki kez yazmak istemiyorsanız, get_text() metodu yardımıyla otomatik olarak etiket metnini alabilirsiniz:
self.etiket.set_markup("<span foreground=<'#610B5E'>%s</span>"%self.etiket.get_text())
Eğer istersek, bu yöntemi kullanarak daha karmaşık işler de yapabiliriz. Mesela bir etiketi farklı renklere boyamak gibi...
import pygtk
pygtk.require20()
import gtk
class Uygulama(object):
def __init__(self):
self.pencere = gtk.Window(gtk.WINDOW_TOPLEVEL)
self.pencere.connect("delete_event", gtk.main_quit)
self.pencere.show()
self.etiket = gtk.Label("Merhaba")
self.renkli1 = self.etiket.get_text()[:4]
self.renkli2 = self.etiket.get_text()[4:]
self.pml = "\
<span foreground='#610B5E'>%s</span>\
<span foreground='#FF0000'>%s</span>"
self.etiket.set_markup(self.pml %(self.renkli1, self.renkli2))
self.pencere.add(self.etiket)
self.etiket.show()
def main(self):
gtk.main()
uyg = Uygulama()
uyg.main()
Burada yaptığımız şey, karakter dizisini dilimlemekten ibaret... Karakter dizisinin ilk dört harfi için bir renk, geri kalan harfleri için ise başka bir renk belirledik.
Bu konuyla ilgili son bir örnek daha vererek yolumuza devam edelim. Bu defa, birkaç örnek önce gösterdiğimiz “sayaç” programında tek sayıları bir renkle çift sayıları başka bir renkle göstermeyi deneyelim:
#-*-coding: utf-8 -*-
import pygtk
pygtk.require20()
import gtk
import time
class Uygulama(object):
def __init__(self):
self.pencere = gtk.Window(gtk.WINDOW_TOPLEVEL)
self.pencere.connect("delete_event", self.kapat)
self.etiket = gtk.Label("başlıyor...")
self.pencere.add(self.etiket)
self.pencere.show()
self.etiket.show()
for i in range(11):
while gtk.events_pending():
gtk.main_iteration()
time.sleep(1)
if i % 2 == 0:
self.etiket.set_markup("<span foreground='red'>%s</span>"%i)
else:
self.etiket.set_markup("<span foreground='blue'>%s</span>"%i)
def kapat(self, penar, event):
gtk.main_quit()
def main(self):
gtk.main()
uyg = Uygulama()
uyg.main()
Burada çok basit bir mantık kullandık. Eğer sayı 2’ye bölündüğünde kalan 0 ise (if i % 2 == 0) bu sayı çifttir. Eğer kalan 0 değilse o sayı tektir... Bu mantığa göre, 2’ye tam bölünen sayılar için “red”, yani kırmızı renk belirledik. Bunu şu kod yardımıyla yaptık:
if i % 2 == 0:
self.etiket.set_markup("<span foreground='red'>%s</span>"%i)
Ama eğer sayı 2’ye tam bölünmüyorsa, renk olarak “blue” yani maviyi seçtik:
else:
self.etiket.set_markup("<span foreground='blue'>%s</span>"%i)
Böylece arayüz üzerindeki sayı değiştikçe, bu sayının çift veya tek olmasına göre, her bir sayıyı iki farklı renkte gösterdik.
3.1.3. Etiketleri Yaslamak¶
Pygtk, oluşturduğumuz etiketleri sağa-sola yaslamamıza izin verir. Bunun için set_justify() adlı bir metottan yararlanabiliriz. Bu metodu şöyle kullanıyoruz:
etiket.set_justify(gtk.JUSTIFY_LEFT)
set_justify() metodu dört farklı parametre alabilir:
- gtk.JUSTIFY_LEFT
- Metodun varsayılan değeri budur. Etiket metnini sola yaslar.
- gtk.JUSTIFY_RIGHT
- Etiket metnini sağa yaslar.
- gtk.JUSTIFY_CENTER
- Etiket metnini ortalar.
- gtk.JUSTIFY_FILL
- Etiket metnini pencere üzerine düzgün olarak dağıtır.
Bu metot tek satırlık etiket metinleri üzerinde hiçbir etkiye sahip değildir. Dolayısıyla set_justify() metodunu kullanabilmek için elimizde birden fazla satırdan oluşan bir etiket olmalı. Buna ufak bir örnek verelim:
#-*-coding: utf-8 -*-
import pygtk
pygtk.require20()
import gtk
class Uygulama(object):
def __init__(self):
self.pencere = gtk.Window(gtk.WINDOW_TOPLEVEL)
self.pencere.connect("delete_event", gtk.main_quit)
self.metin = """
Adana, Türkiye'nin güneyinde,
Doğu Akdeniz'in kuzeyinde yer alan ildir.
İl merkezinin adı da Adana olup,
Seyhan, Yüreğir, Çukurova, Sarıçam ve
Karaisalı ilçelerinin birleşimiyle oluşur.
"""
self.etiket = gtk.Label(self.metin)
self.etiket.set_justify(gtk.JUSTIFY_CENTER)
self.pencere.add(self.etiket)
self.pencere.show_all()
def main(self):
gtk.main()
uyg = Uygulama()
uyg.main()
3.1.4. Etiketleri Seçilebilir Hale Getirmek¶
Pygtk’de “Label” pencere aracını kullanarak bir etiket oluşturduğumuzda, varsayılan olan etiket metnini fare ile seçemeyiz. Dolayısıyla, yazdığımız programdaki etiket metnini kopyalama imkanımız da yoktur. Ancak Pygtk’deki set_selectable() adlı bir metodun değerini değiştirerek bu durumu tersine çevirebiliriz:
#-*-coding: utf-8 -*-
import pygtk
pygtk.require20()
import gtk
class Uygulama(object):
def __init__(self):
self.pencere = gtk.Window(gtk.WINDOW_TOPLEVEL)
self.pencere.connect("delete_event", gtk.main_quit)
self.metin = """
Adana, Türkiye'nin güneyinde,
Doğu Akdeniz'in kuzeyinde yer alan ildir.
İl merkezinin adı da Adana olup,
Seyhan, Yüreğir, Çukurova, Sarıçam ve
Karaisalı ilçelerinin birleşimiyle oluşur.
"""
self.etiket = gtk.Label(self.metin)
self.etiket.set_selectable(True)
self.pencere.add(self.etiket)
self.pencere.show_all()
def main(self):
gtk.main()
uyg = Uygulama()
uyg.main()
Burada set_selectable() metodunun değerini “True” yaptığımız için, etiket metni fare ile seçilebilir. Ayrıca bu etiket üzerinde farenin sağ tuşu da çalışacak, böylece etiket metnini kopyalayabileceksiniz.
3.2. “Button” Pencere Aracı¶
gtk.Label() adlı pencere aracıyla yeterince çalıştık. Öğrenme sürecimizin sıkıcı bir hal almaması için dilerseniz yeni bir pencere aracı daha görelim. Hem böylece Pygtk’deki olanaklarımız da artmış olur...
Şimdi öğreneceğimiz pencere aracının adı “gtk.Button()”. “Button” kelimesi “düğme” anlamına gelir. Dolayısıyla bu pencere aracı programlarımıza düğme ekleme imkanı sağlayacak bize. “Button” pencere aracının kullanımı az çok “Label” pencere aracınınkine benzer. Bir Pygtk uygulamasında düğme oluşturmak için şu kodu kullanıyoruz:
dugme = gtk.Button("düğme")
Burada “gtk.Button()” fonksiyonu düğmenin kendisidir. Fonksiyona parametre olarak atadığımız “düğme” kelimesi ise, oluşturduğumuz düğme üzerinde görünecek yazıdır. İsterseniz bunu bir örnek içinde kullanalı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.connect("delete_event", gtk.main_quit)
self.dugme = gtk.Button("düğme")
self.dugme.show()
self.pencere.add(self.dugme)
self.pencere.show()
def main(self):
gtk.main()
uyg = Uygulama()
uyg.main()
Bu şekilde, üzerinde “düğme” yazan bir düğme oluşturmuş olduk... Yalnız burada düğmeyi oluşturma adımlarına çok dikkat ediyoruz. Düğme oluştururken şu adımları takip ettik:
Öncelikle “self.dugme = gtk.Button(“düğme”)” satırı yardımıyla pencere üzerinde bir düğme meydana getiriyoruz. Burada “gtk” modülünün Button() fonksiyonunu kullandık ve bu fonksiyona “self.dugme” adını verdik. Oluşturacağımız düğmenin üzerinde ne yazacağını ise Button() fonksiyonunun içinde bir parametre olarak belirliyoruz. Bizim örneğimizde oluşturduğumuz düğmenin üzerinde “düğme” kelimesi yazacak.
İkinci adım olarak, düğmemizi “gösteriyoruz”. Bu işlemi de “self.dugme.show()” satırı yardımıyla gerçekleştiriyoruz. Eğer bu satırı yazmazsak düğmemiz yine de oluşur, ama ekranda görünmez!
Atmamız gereken son adım ise bu düğmeyi ana pencereye “eklemek” olacaktır. İşte “self.pencere.add(self.dugme)” satırı bu işe yarıyor...
Dikkat ederseniz oluşturduğumuz düğme, pencerenin tamamını kaplıyor. Yani düğmemiz ana pencerenin içine, etrafında hiç boşluk bırakmayacak şekilde yerleşmiş... Eğer düğmemizin etrafında biraz boşluk bırakmak istersek set_border_width() adlı 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.connect("delete_event", gtk.main_quit)
self.dugme = gtk.Button("düğme")
self.dugme.set_border_width(30)
self.dugme.show()
self.pencere.add(self.dugme)
self.pencere.show()
def main(self):
gtk.main()
uyg = Uygulama()
uyg.main()
Burada yazdığımız “self.dugme.set_border_width(30)” satırı, düğmenin dört tarafında 30 piksellik boş bir alan oluşturuyor. Aynı metodu, istersek ana pencereye de uygulayabiliriz. Bu metodu ana pencereye uyguladığımızda, pencere içinde belirlediğimiz piksel sayısı kadar bir alan oluşacaktır:
#-*-coding:utf-8-*-
import pygtk
pygtk.require20()
import gtk
class Uygulama(object):
def __init__(self):
self.pencere = gtk.Window(gtk.WINDOW_TOPLEVEL)
self.pencere.connect("delete_event", gtk.main_quit)
self.pencere.set_border_width(30)
self.dugme = gtk.Button("düğme")
self.dugme.show()
self.pencere.add(self.dugme)
self.pencere.show()
def main(self):
gtk.main()
uyg = Uygulama()
uyg.main()
Temel olarak Pygtk’de bir düğmeyi nasıl oluşturacağımızı öğrendiğimize göre artık yolumuza devam edebiliriz. Bir düğme elbette üzerine tıklandığında bir işlevi yerine getirebilirse işe yarar bir hal alacaktır. Bir sonraki bölümde, düğmelerimize nasıl görev atayacağımızı öğreneceğiz.
3.2.1. Düğmelere Görev Atamak¶
Daha önceki derslerimizde ana pencereye nasıl görev atayacağımızı öğrenmiştik. Hatırlarsanız, Pygtk’yi kendi haline bıraktığımızda, ana penceredeki çarpı düğmesine tıklamamız aslında programın kapanmasını sağlamıyordu. Programımızı başarıyla kapatabilmek için ana pencerenin çarpı düğmesine bir görev atamamız gerekiyordu. Bu işlemi şöyle yapıyorduk:
#-*-coding:utf-8-*-
import pygtk
pygtk.require20()
import gtk
class Uygulama(object):
def __init__(self):
self.pencere = gtk.Window(gtk.WINDOW_TOPLEVEL)
self.pencere.connect("delete_event", gtk.main_quit)
self.pencere.show()
def main(self):
gtk.main()
uyg = Uygulama()
uyg.main()
Kodlarımızı bu şekilde yazdığımız zaman, pencerenin çarpı düğmesine tıkladığımızda programımız tamamen kapanacaktır. Biz yukarıdaki örnekte işimizi tek satırda hallettik. Yani gtk.main_quit kodunu doğrudan “self.pencere.connect()” fonksiyonuna bir parametre olarak atadık. Ama eğer istersek bu parametreyi ayrı bir fonksiyon olarak da yazabileceğimizi biliyoruz:
#-*-coding:utf-8-*-
import pygtk
pygtk.require20()
import gtk
class Uygulama(object):
def __init__(self):
self.pencere = gtk.Window(gtk.WINDOW_TOPLEVEL)
self.pencere.connect("delete_event", self.kapat)
self.pencere.show()
def kapat(self, penar, event):
gtk.main_quit()
def main(self):
gtk.main()
uyg = Uygulama()
uyg.main()
Burada kapat() adlı fonksiyonumuzun en az iki parametre aldığına dikkat ediyoruz (penar ve event). “penar” adlı parametre kapat() adlı fonksiyonun bağlanacağı “pencere aracını”; “event” adlı parametre ise çarpı işaretine tıklandığında gerçekleşecek olayı temsil ediyor. Bizim örneğimizde “penar” ana pencerenin kendisi oluyor. “event” ise “delete_event”...
Düğmelere görev atamak istediğimizde de buna benzer bir yöntem kullanıyoruz. Şimdi mesela bir düğme oluşturalım ve bu düğmeye tıkladığımızda programımız kapansın:
#-*-coding: utf-8-*-
import pygtk
pygtk.require20()
import gtk
class Uygulama(object):
def __init__(self):
self.pencere = gtk.Window(gtk.WINDOW_TOPLEVEL)
self.pencere.connect("delete_event", gtk.main_quit)
self.pencere.set_border_width(10)
self.pencere.show()
self.dugme = gtk.Button("Kapat")
self.dugme.connect("clicked", gtk.main_quit)
self.dugme.show()
self.pencere.add(self.dugme)
def main(self):
gtk.main()
uyg = Uygulama()
uyg.main()
Burada basitçe “clicked” adlı sinyali “gtk.main_quit” adlı fonksiyona bağladık. “clicked”, Pygtk’de fare ile tıklama hareketini ifade eder. Burada düğme üzerine fare ile tıklandığında gtk.main_quit() adlı fonksiyon faaliyete geçecektir. Bu fonksiyonun pencereyi kapatma vazifesi gördüğünü biliyoruz. Dolayısıyla ana pencere üzerindeki “Kapat” adlı düğmeye fare ile tıkladığımızda penceremiz (ve tabii ki programımız) kapanacaktır.
Burada gtk.main_quit() fonksiyonunu doğrudan connect() fonksiyonu içinde belirttik. Düğmeye tıklandığında daha karmaşık işlemler yapabilmemiz için çoğunlukla ayrı bir fonksiyon yazmamız gerekecektir. İsterseniz hemen buna bir örnek verelim:
#-*-coding:utf-8-*-
import pygtk
pygtk.require20()
import gtk
class Uygulama(object):
def __init__(self):
self.pencere = gtk.Window(gtk.WINDOW_TOPLEVEL)
self.pencere.connect("delete_event", gtk.main_quit)
self.pencere.set_border_width(10)
self.pencere.show()
self.dugme = gtk.Button("Kapat")
self.dugme.connect("clicked", self.kapat)
self.dugme.show()
self.pencere.add(self.dugme)
def kapat(self, penar):
gtk.main_quit()
def main(self):
gtk.main()
uyg = Uygulama()
uyg.main()
Burada dikkat etmemiz gereken birkaç nokta var: Kodlarımız içinde tanımladığımız kapat() adlı fonksiyon “self” dışında en az “1” parametre daha almak zorunda... kapat() fonksiyonu için belirlediğimiz “penar” adlı parametre, kapat() fonksiyonunun hangi pencere aracına bağlanacağını gösteriyor. Bizim örneğimizde bu fonksiyon “self.dugme” adlı pencere aracına bağlanıyor. Bu arada, buradaki “kapat” fonksiyonunu “self.pencere.connect(“delete_event”, self.kapat)” şeklinde ana pencereye atayamayacağımıza dikkat edin... Neden? Çünkü “delete_event” adlı olay (event), bağlı olduğu fonksiyonun en az “2” parametreye sahip olmasını gerektirir (“self” hariç). “clicked” adlı sinyal (signal) ise bağlı olduğu fonksiyonun en az “1” parametre almasını gerektirir... Dolayısıyla olayların (event) ve sinyallerin (signals) gerektirdiği parametre sayısı farklı olduğu için aynı fonksiyonu hem “olaylar” hem de “sinyaller” için kullanamıyoruz. Ama ümitsizliğe kapılmayın! “Kullanamıyoruz,” dediysek “hiç kullanamıyoruz,” demedik!... Bu sorunun üstesinden gelmenin de bir yolu yordamı var. “kapat” adlı fonksiyona üçüncü bir parametre daha ekleyip buna da varsayılan olarak “None” değeri verirsek sorunumuzu halletmiş oluruz...
#-*-coding:utf-8-*-
import pygtk
pygtk.require20()
import gtk
class Uygulama(object):
def __init__(self):
self.pencere = gtk.Window(gtk.WINDOW_TOPLEVEL)
self.pencere.connect("delete_event", self.kapat)
self.pencere.set_border_width(10)
self.pencere.show()
self.dugme = gtk.Button("Kapat")
self.dugme.connect("clicked", self.kapat)
self.dugme.show()
self.pencere.add(self.dugme)
def kapat(self, penar, event=None):
gtk.main_quit()
def main(self):
gtk.main()
uyg = Uygulama()
uyg.main()
Böylece aynı kapat() fonksiyonunu hem pencereye hem de pencere aracına atamış olduk...
Burada özel olarak dikkat etmemiz gereken öğe “clicked” adlı sinyaldir. İşin asıl kısmını gerçekleştirmemizi bu sinyal sağlar. Pygtk’da düğmeler temel olarak şu sinyalleri üretir:
- clicked
- fare ile düğme üzerine tıklanıp bırakılma anı
- pressed
- fare ile düğme üzerine basılma anı
- released
- farenin tuşunun serbest bırakılma anı
- enter
- imlecin düğmenin üzerine gelme anı
- leave
- imlecin düğmeyi terketme anı
Bu sinyaller içinde “clicked” ve “released” adlı sinyaller, davranışları bakımından birbirine çok benzer. İki sinyal de, fare tuşuna basıldığında değil, farenin tuşu bırakıldığında üretilecektir. Ancak bu iki sinyal arasında önemli bir fark vardır. “clicked” sinyalini kullandığımızda, farenin tuşuna basıp, tuşu bırakmadan fare imlecini düğmeden uzaklaştırırsak ve bundan sonra farenin tuşunu serbest bırakırsak üzerine tıkladığımız düğme işlevini yerine getirmeyecektir. Ama “released” sinyalini kullandığımızda, farenin tuşuna basıp, tuşu bırakmadan fare imlecini düğmeden uzaklaştırsak dahi, farenin tuşunu serbest bırakır bırakmaz ana pencere üzerindeki düğme işlevini yerine getirecektir... Bu ikisi arasındaki farkı daha net anlamak için iki sinyalin ayrı ayrı kullanıldığı kodlar yazıp, sonucu incelemenizi öneririm.
Yukarıda verdiğimiz beş farklı sinyal içinde işimize en çok yarayacak olan, “clicked” adlı sinyaldir. Öteki sinyallere, yazdığımız programlarda nispeten daha az ihtiyaç duyacağız...
Gelin şimdi bu öğrendiklerimizi pratiğe döken basit bir uygulama yazalım:
#-*-coding:utf-8-*-
import pygtk
pygtk.require20()
import gtk
class Uygulama(object):
def __init__(self):
#Her düğmeye tıklayışımızda farklı bir dil
#adı gösteren bir uygulama yazıyoruz... Bunun için öncelikle dilleri
#içeren bir liste oluşturuyoruz.
self.diller = ["Türkçe", "İngilizce", "Almanca", "Fransızca", "İtalyanca"]
#self.diller adlı listedeki öğelere erişmek için aşağıdaki
#index değerini kullanacağız.
self.index = 0
#Uygulamamızın ana penceresini oluşturuyoruz.
self.pencere = gtk.Window(gtk.WINDOW_TOPLEVEL)
#Uygulamamızın düzgün kapanması için "delete_event"i
#"gtk.main_quit()" adlı fonksiyona bağlıyoruz.
self.pencere.connect("delete_event", gtk.main_quit)
#Penceremizin başlığını belirliyoruz.
self.pencere.set_title("Örnek bir uygulama...")
#Penceremizi ekranın ortasında konumlandırıyoruz.
self.pencere.set_position(gtk.WIN_POS_CENTER)
#Penceremizin boyutunu belirliyoruz.
self.pencere.resize(100, 100)
#Penceremizi gösteriyoruz.
self.pencere.show()
#Üzerinde "Başla!" yazan bir düğme...
self.dugme = gtk.Button("Başla!")
#Düğmemizin etrafında biraz boşluk bırakalım.
self.dugme.set_border_width(25)
#Düğme üzerine basıldığında "self.say" adlı fonksiyon
#çalışmaya başlasın.
self.dugme.connect("pressed", self.say)
#Düğmemizi ana pencereye ekliyoruz.
self.pencere.add(self.dugme)
#Düğmemizi gösteriyoruz.
self.dugme.show()
def say(self, penar):
#düğmemizin etiketini değiştiriyoruz. index değeri her
#defasında bir sayı artarak ilerleyeceği için, bu index
#değerini self.diller adlı listenin öğelerine tek tek
#erişmek amacıyla kullanabiliriz.
self.dugme.set_label(self.diller[self.index])
#Düğmeye her basışta index değerini 1 sayı artıralım.
self.index += 1
#index değeri listenin sonuncu öğesine ulaşınca
#programımızın hata vermemesi için index değerini
#sıfırlıyoruz. Böylece liste öğelerini almaya
#tekrar en baştan başlayabiliyoruz.
if self.index == len(self.diller):
self.index = 0
def main(self):
#Uygulamamızın dinamosu...
gtk.main()
uyg = Uygulama()
uyg.main()
Daha önce de söylediğimiz gibi, bir düğmeye görev atayacağımız zaman, atanacak işlevi içeren fonksiyonu yazarken bu fonksiyonun “self” ile birlikte en az 2 parametre içermesine dikkat ediyoruz. Esasında, yazacağımız bu fonksiyon üçüncü bir parametre daha içerebilir. Bu üçüncü parametreyi şöyle kullanabiliriz:
#-*-coding:utf-8-*-
import pygtk
pygtk.require20()
import gtk
class Uygulama(object):
def __init__(self):
self.sayac = 0
self.pencere = gtk.Window(gtk.WINDOW_TOPLEVEL)
self.pencere.connect("delete_event", gtk.main_quit)
self.pencere.set_border_width(10)
self.pencere.set_position(gtk.WIN_POS_CENTER)
self.dugme = gtk.Button("Tamam")
self.pencere.add(self.dugme)
self.dugme.connect("clicked", self.bas, "Tamam")
self.dugme.show()
self.pencere.show()
def bas(self, penar, veri):
self.sayac += 1
print "%s düğmesine %s kez bastınız!" %(veri, self.sayac)
def main(self):
gtk.main()
uyg = Uygulama()
uyg.main()
Burada bas() adlı fonksiyona üçüncü bir parametre ekledik ve bu parametrenin adını “veri” koyduk. Elbette siz isterseniz buna başka bir ad da verebilirsiniz... Bu yeni parametreyi temsil eden veriyi de connect() fonksiyonu içinde belirttik (“Tamam”). Burada düğmenin adı olan “Tamam”ı doğrudan yazmak yerine şöyle bir şey de yapabilirsiniz tabii ki:
self.dugme.connect(“clicked”, self.bas, self.dugme.get_label())
Bu şekilde kodlarımızı daha esnek bir hale getirmiş oluyoruz...
Bu arada eğer komut satırında Türkçe karakterleri gösteremiyorsanız bas() fonksiyonu içindeki karakter dizisini şöyle yazdırabilirsiniz:
print u"%s düğmesine %s kez bastınız!" %(veri, self.sayac)
Burada karakter dizisini Unicode olarak belirlediğimize dikkat edin...
3.2.2. Düğmelerin Rengini Değiştirmek¶
Normal şartlar altında Pygtk uygulamalarında kullanacağınız düğmelerin rengini değiştirmeye ihtiyaç duyacağınızı zannetmiyorum. Ama eğer olur da farklı renkte düğmeler kullanmak istersiniz diye Pygtk size bu isteğinizi gerçekleştirmenizi sağlayacak araçlar da sunar...
Pygtk’de bir düğmenin rengini değiştirmek için modify_bg() adlı bir metottan yararlanacağız. Ancak bir düğmenin rengini değiştirebilmek için bundan fazlasını bilmeye ihtiyacımız var. Çünkü Pygtk’de düğme rengini belirlerken renk adını dümdüz kullanamazsınız. İsterseniz lafı uzatmadan bir örnek verelim:
#-*-coding: utf-8-*-
import pygtk
pygtk.require20()
import gtk
class Uygulama(object):
def __init__(self):
self.pencere = gtk.Window(gtk.WINDOW_TOPLEVEL)
self.pencere.connect("destroy", gtk.main_quit)
self.pencere.set_border_width(30)
self.btn = gtk.Button("deneme")
#şimdi düğmenin rengini değiştiriyoruz...
self.btn.modify_bg(gtk.STATE_NORMAL, gtk.gdk.Color("red"))
self.pencere.add(self.btn)
self.pencere.show_all()
def main(self):
gtk.main()
uyg = Uygulama()
uyg.main()
Gördüğünüz gibi kırmızı renkte bir düğme oluşturduk... Burada ilk olarak modify_bg() adlı bir metot görüyoruz. Ancak bu metodun düğme rengini değiştirebilmesi için bazı parametrelere ihtiyacı var. Bu metodun aldığı ilk parametre “gtk.STATE_NORMAL”. Bu ifade bir pencere aracının durumunu gösteriyor. Pygtk’de pencere araçları beş farklı durumda bulunabilir:
gtk.STATE_NORMAL
Bir pencere aracının herhangi bir işlem yapılmıyorkenki durumu. Mesela bir program başlatıldığında, arayüz üzerindeki düğmeler “gtk.STATE_NORMAL” denen durumdadır. Yukarıda verdiğimiz örnekte düğmenin rengini, bu gtk.STATE_NORMAL denen durum için değiştiriyoruz. Eğer düğmenin üzerine fare ile gelecek olursanız düğme renginin eski haline döndüğünü göreceksiniz. Çünkü fare ile üzerine geldiğinizde düğmemiz artık gtk.STATE_NORMAL denen durumda olmayacaktır...
gtk.STATE_PRELIGHT
Bir pencere aracının üzerine fare ile gelindiğindeki durumu. Yukarıdaki örnekte düğme üzerine fare ile geldiğinizde düğmenin renginin eski haline döndüğünü gördünüz. İşte düğmenin üzerine fare ile geldiğiniz duruma “gtk.STATE_PRELIGHT” adı verilir. Yukarıdaki örnekte ilgili satırı şöyle değiştirin:
self.btn.modify_bg(gtk.STATE_PRELIGHT, gtk.gdk.Color("red"))
Şimdi düğmenin üzerine fare ile geldiğinizde düğmenin kırmızıya döndüğünü göreceksiniz. Çünkü bu defa düğme rengini “gtk.STATE_NORMAL” için değil, “gtk_STATE_PRELIGHT” için değiştirdik...
gtk.STATE_ACTIVE
Bir pencere aracının aktif olduğu duruma “gtk.STATE_ACTIVE” adı verilir. Mesela bir düğmeye bastığınız anda o düğme “gtk.STATE_ACTIVE” denen duruma geçer. Yukarıdaki örneğin ilgili satırını şöyle değiştirin:
self.btn.modify_bg(gtk.STATE_ACTIVE, gtk.gdk.Color("red"))
Şimdi düğmeye tıkladığınızda düğme kırmızıya dönecek, bıraktığınızda ise eski rengini alacaktır.
gtk.STATE_SELECTED
Bir pencere aracının seçili olduğu duruma “gtk.STATE_SELECTED” adı verilir. Henüz bir buna örnek olarak gösterebileceğimiz bir pencere aracı öğrenmedik, ama mesela bir liste kutusu içindeki seçili satır gtk.STATE_SELECTED durumuna örnek olarak verilebilir...
gtk.STATE_INSENSITIVE
Bir pencere aracının meşgul olduğu duruma “gtk.STATE_INSENSITIVE” adı verilir. Henüz bunun için de verecek bir örneğimiz yok. Ama zamanla olacak...
Düğmenin rengini değiştirmek için yazdığımız koddaki modify_bg() ve gtk.STATE_ACTIVE kısımlarını anladık. İncelememiz gereken sadece “gtk.gdk.Color(“red”)) kısmı kaldı...
gtk.gdk.Color(), renkleri tutma görevi gören bir sınıftır. Temel renkler için İngilizce renk adlarından yararlanabiliriz. Veya daha önce de gördüğümüz gibi http://html-color-codes.info/ adresindeki onaltılık renk kodlarını kullanabiliriz. Eğer isterseniz RGB renk kodlarını da gtk.gdk.Color() sınıfı içinde kullanabilirsiniz. Bu sınıf bu haliyle GNU/Linux üzerinde herhangi bir sorun çıkarmadan çalışacaktır. Ancak Windows üzerinde bu sınıfı çalıştırmak istediğinizde “TypeError: an integer is required” gibi bir hata alıyorsanız gtk.gdk.Color() sınıfı yerine gtk.gdk.color_parse() sınıfından da yararlanabilirsiniz:
self.btn.modify_bg(gtk.STATE_NORMAL, gtk.gdk.color_parse("red"))
Eğer Windows üzerinde bu kodlar da beklediğiniz sonucu vermiyorsa sorun kullandığınız temadadır. Başlat > Programlar > GTK+ > Theme Selector yolunu takip ederek mevcut GTK temasını değiştirmeyi deneyin. Eğer “Theme Selector” uygulaması Başlat menüsünde görünmüyorsa, “C\GTK\bin” klasörü içinde “gtkthemeselector.exe” adlı uygulamayı bulup buna çift tıklayarak da tema seçici programı başlatabilirsiniz...