Python (11. Bölüm)

Wiki.Pardus-Linux.Org sitesinden

Git ve: kullan, ara

Forum'da bu konunun tartışma adresi: http://forum.pardus-linux.org/viewtopic.php?t=10478


Konu başlıkları

Grafik Arayüz Tasarımı // Pencere Araçları (Widgets)

Giriş

Herhangi bir pencere üzerinde bulunan düğmeler, etiketler, sağa-sola, yukarı-aşağı kayan çubuklar, kutular, menüler, vb. hepsi birden pencere araçlarını, yani widget'leri, oluşturuyor.

Aslında şimdiye kadar bu pencere araçlarından bir tanesini gördük. Bildiğimiz bir pencere aracı olarak elimizde şimdilik "Label" bulunuyor:

"Label" Pencere Aracı

Daha önce de söylediğimiz gibi bu kelime İngilizce'de "etiket" anlamına geliyor. Bu araç, anlamına uygun olarak pencerelerin üzerine etiket misali öğeler yapıştırmamızı sağlıyor.

Hatırlayacağınız gibi bu aracı "Label()" şeklinde kullanıyorduk. İsterseniz bununla ilgili olarak hemen basit bir örnek verelim:

#!/usr/bin/env python
#-*-coding:utf-8-*-
from Tkinter import *
pencere = Tk()
etiket = Label(text = "Hata: Bellek Read Olamadı! Belleği vurmamı ister misiniz?")
etiket.pack()
mainloop()

Gördüğünüz gibi yukarıdaki kullanımda "Label" aracı bir metnin pencere üzerinde görüntülenmesini sağlıyor.

"Button" Pencere Aracı

Bu araç yardımıyla pencerelerimize, tıklandıklarında belli bir işlevi yerine getiren düğmeler ekleyebileceğiz. Hemen bir örnek verelim:

#!/usr/bin/env python
#-*-coding:utf-8-*-
from Tkinter import *
pencere = Tk()
dugme = Button(text="TAMAM", command = pencere.quit)
dugme.pack()
mainloop()

Dikkat ederseniz, "Button" aracının kullanımı daha önce gördüğümüz "Label" aracının kullanımına çok benziyor. Burada da parantez içinde bazı parametreler kullandık. "text" parametresini zaten biliyoruz: Kullanıcıya göstermek istediğimiz metni bu "text" parametresi yardımıyla belirliyoruz. Aynı parantez içinde gördüğümüz "command" parametresi ise düğme üzerine tıklandığında işletilecek komutu gösteriyor. Biz burada "pencere.quit" komutunu vererek, düğmeye tıklandığında pencerenin kapatılmasını istedik.

Dolayısıyla bir satır içinde üç yeni özellik görmüş oluyoruz:

Button = Kullanacağımız pencere aracı ("button" : "düğme")
command = Oluşturduğumuz düğmeye tıklandığında çalıştırılacak komut
xxx.quit = Düğmeye tıklandığında pencerenin kapatılmasını sağlayan komut.

Daha sonra gelen satırdaki ifade size tanıdık geliyor olmalı: "dugme.pack()". Tıpkı daha önce "etiket.pack()" ifadesinde gördüğümüz gibi, bu ifade de hazırladığımız pencere aracının kargoya verilmek üzere "paketlenmesini" sağlıyor.

En son satırdaki "mainloop()" ifadesinin ne işe yaradığını artık söylemeye bile gerek yok...

Yukarıda bahsettiğimiz "command" parametresi çok güzel işler yapmanızı sağlayabilir. Mesela diyelim ki, "oluştur" düğmesine basınca bilgisayarda yeni bir dosya oluşturan bir arayüz tasarlamak istiyoruz. O halde hemen bu düşüncemizi tatbik sahasına koyalım:

#!/usr/bin/env python
#-*-coding:utf-8-*-
from Tkinter import *
def olustur():
        dosya = open("deneme.txt", "w")

pencere = Tk()
dugme = Button(text = "oluştur", command=olustur)
dugme.pack()
mainloop()

Gördüğünüz gibi, Tkinter modülünü çağırdıktan sonra bir fonksiyon oluşturduk. Tkinter dışından bir komut çalıştırmak istediğimizde bu şekilde bir fonksiyon tanımlamamız gerekir.

Daha sonra her zaman yaptığımız gibi, "Tk()" komutuyla penceremizi oluşturduk. Button() yardımıyla da pencereye yerleştireceğimiz düğmeyi meydana getirdik. Burada "command" parametresine biraz önce oluşturduğumuz fonksiyonu atayarak düğmeye basıldığında yeni bir dosya oluşturulmasına zemin hazırladık. "text" parametresi yardımıyla da düğmemizin adını "oluştur" olarak belirledik. Ondan sonraki satırları ise zaten artık ezbere biliyoruz.

Eğer bu kodları yazarken, yukarıdaki gibi bir fonksiyon oluşturmadan;

dugme = Button(text = "oluştur", command=open("deneme.txt","w"))

gibi bir satır oluşturursanız, "deneme.txt" adlı dosya düğmeye henüz basmadan oluşacaktır...

İsterseniz bu arayüze bir de "çıkış" düğmesi ekleyebiliriz:

#!/usr/bin/env python
#-*-coding:utf-8-*-
from Tkinter import *
def olustur():
        dosya = open("deneme.txt", "w")

pencere = Tk()
dugme = Button(text = "oluştur", command=olustur)
dugme.pack()
dugme2 = Button(text = "çıkış", command=pencere.quit)
dugme2.pack()
mainloop()

Burada yaptığımız şey, ikinci bir düğme oluşturmaktan ibaret... Oluşturduğumuz "dugme2" adlı değişken için de "dugme2.pack" ifadesini kullanmayı unutmuyoruz.

Düğmelerin pencere üstünde böyle alt alta görünmesini istemiyor olabilirsiniz. Herhalde yan yana duran düğmeler daha zarif görünecektir. Bunun için kodumuza şu eklemeleri yapmamız gerekiyor:

#!/usr/bin/env python
#-*-coding:utf-8-*-
from Tkinter import *
def olustur():
        dosya = open("deneme.txt", "w")

pencere = Tk()
dugme = Button(text = "oluştur", command=olustur)
dugme.pack(side=LEFT)
dugme2 = Button(text = "çıkış", command=pencere.quit)
dugme2.pack(side=RIGHT)
mainloop()

“Paketleme” aşamasında düğmelerden birine “side=LEFT” parametresini ekleyerek o düğmeyi sola; öbürüne de “side=RIGHT” parametresini ekleyerek sağa yaslıyoruz.

"Entry" Pencere Aracı

Bu araç yardımıyla kullanıcının metin girebileceği tek satırlık bir alan oluşturacağız. Bu pencere aracının kullanımı da diğer araçların kullanımına benzer. Hemen bir örnek verelim:

from Tkinter import *
pencere = Tk()
giris = Entry()
giris.pack()
mainloop()

Her zamanki gibi ilk önce Tkinter modülünü çağırarak işe başladık. Hemen ardından da "pencere" adını verdiğimiz boş bir pencere oluşturduk. Dediğimiz gibi, "Entry" aracının kullanımı daha önce sözünü ettiğimiz pencere araçlarının kullanımına çok benzer. Dolayısıyla "giris" adını verdiğimiz "Entry()" aracını rahatlıkla oluşturabiliyoruz. Bundan sonra yapmamız gereken şey, tabii ki, bu pencere aracını paketlemek. Onu da "giris.pack()" satırı yardımıyla hallediyoruz. Son darbeyi ise "mainloop" komutuyla vuruyoruz.

Gördüğünüz gibi, kullanıcıya tek satırlık metin girme imkanı veren bir arayüz oluşturmuş olduk. İsterseniz şimdi bu pencereye birkaç düğme ekleyerek daha işlevli bir hale getirelim arayüzümüzü. Mesela pencere üzerinde programı kapatmaya yarayan bir düğme ve kullanıcının yazdığı metni silen bir düğme bulunsun:

#!/usr/bin/env python
#-*- coding: utf-8 -*- 
from Tkinter import *

def sil():
	giris.delete(0,END)
pencere = Tk()
giris = Entry()
giris.pack()
dugme1 = Button(text = "KAPAT", command = pencere.quit)
dugme1.pack(side = LEFT)
dugme2 = Button(text = "SİL", command = sil)
dugme2.pack(side = RIGHT)
mainloop()

Bu kodlar içinde bize yabancı olan tek ifade "giris.delete(0, END)". Bu komut, görünüşünden de anlaşılacağı gibi, "giris" değişkeninin içeriğini silmeye yarıyor. Parantez içindeki "0, END" ifadesi, metin kutusuna girilen kelimenin en başından en sonuna kadar bütün harflerin silinmesi emrini veriyor. Eğer "0, END" yerine, mesela "2, 4" gibi bir ifade koysaydık, girilen kelimenin 2. harfinden itibaren 4. harfine kadar olan kısmın silinmesi emrini vermiş olacaktık. Son bir alıştırma yaparak bu aracı da tamamlayalım:

#!/usr/bin/env python
#-*- coding:utf-8-*-
from Tkinter import *

def olustur():
	dosya = open("deneme.txt","w")
	metin = giris.get()
	dosya.write(metin)
	
pencere = Tk()
giris = Entry()
giris.pack()
dugme = Button(text = "OLUŞTUR", command = olustur)
dugme.pack(side=LEFT)
dugme2 = Button(text = "ÇIK", command = pencere.quit)
dugme2.pack(side=RIGHT)

mainloop()

Burada da bize yabancı olan tek ifade "giris.get()"... Bu ifade "Entry" pencere aracı ile kullanıcıdan aldığımız metni elimizde tutup saklamamızı sağlıyor. Burada bu ifadeyi önce "metin" adlı bir değişkene atadık, sonra da bu metin değişkeninin içeriğini "dosya.write(metin)" komutunun yardımıyla boş bir dosyaya aktardık. Metin kutusunun içeriğini barındıran "deneme.txt" isimli dosya /home klasörünüzün altında veya masaüstünde oluşmuş olmalı...

Bir örnek daha yapalım...

#!/usr/bin/env python
#-*-coding:utf-8-*-
from Tkinter import *
import random

def bas():
	a = random.randint(1,100)
	giris.delete(0,END)
	giris.insert(0, a)
	
pencere = Tk()

giris = Entry(width=10)
giris.pack()

dugme = Button(text="bas", command=bas, width=2, height=0)
dugme.pack()

mainloop()

Gördüğünüz gibi, bu uygulama 1 ile 100 arasında rastgele sayılar seçiyor... Aslında yaptığımız işlem çok basit:

Öncelikle Python'un "random" adlı modülünü çağırdık. Rastgele sayılar seçerken bize bu modül yardımcı olacak. Ardından da bu rastgele sayıları oluşturup ekrana yazdırmamızı sağlayacak fonksiyonu oluşturuyoruz. Bu fonksiyonda öncelikle rastgele sayıların hangi aralıkta olacağını belirleyip bunu "a" adlı bir değişkene atıyoruz. Böylece rastgele sayıları ekrana yazdırmak için gereken altyapıyı oluşturmuş olduk. Şimdi bu noktada eğer bir önlem almazsak ekrana basılacak sayılar yan yana sıralanacaktır. Yani mesela diyelim ki ilk rastgele sayımız 3 olsun. Bu 3 sayısı ekrana yazıldıktan sonra ikinci rastgele sayı ekrana gelmeden önce bu ilk sayının ekrandan silinmesi gerekiyor. Bütün sayılar yan yana ekrana dizilmemeli. Bunun için kodumuza şu satırı ekliyoruz:

giris.delete(0,END)

Bu satır sayesinde, ilk sayı ekrana basıldıktan sonra ekranın 0. konumundan sonuncu konumuna kadar bütün her şeyi siliyoruz. Böylelikle ikinci gelecek sayı için yer açmış oluyoruz. İsterseniz yukarıdaki kodları bu satır olmadan çalıştırmayı bir deneyebilirsiniz. Ondan sonra gelen satırın ne işe yaradığını anlamışsınızdır: "a" değişkenini 0. konuma yerleştiriyoruz. Fonksiyonumuzu böylece tamamlamış olduk. Daha sonra normal bir şekilde "Entry" ve Button" adlı pencere araçları yardımıyla düğmelerimizi ve metin alanımızı oluşturuyoruz. Burada bazı yeni "seçenekler" dikkatiniz çekmiş olmalı: Bunlar, "width" ve "height" adlı seçenekler... "width" seçeneği yardımıyla bir pencere aracının genişliğini; "height" seçeneği yardımıyla ise o aracın yüksekliğini belirliyoruz.

"Checkbutton" Pencere Aracı

"Checkbutton" denen şey, bildiğimiz "onay kutusu"... Basitçe şu şekilde oluşturuyoruz bu onay kutusunu:

#!/usr/bin/python
#-*-coding=utf-8-*-
from Tkinter import *
pencere = Tk()
onay = Checkbutton()
onay.pack()
mainloop()

Tabii ki muhtemelen bu onay kutumuzun, hatta kutularımızın birer adı olsun isteriz:

#!/usr/bin/python
#-*-coding=utf-8-*-
from Tkinter import *
pencere = Tk()
onay_el = Checkbutton(text="elma")
onay_el.pack()
onay_sa = Checkbutton(text="salatalık")
onay_sa.pack()
onay_do = Checkbutton(text="domates")
onay_do.pack()
onay_ka = Checkbutton(text="karnıbahar")
onay_ka.pack()
mainloop()

Gayet güzel.. Ama gördüğünüz gibi öğeler alt alta sıralanırken hizalı değiller. Dolayısıyla göze pek hoş görünmüyorlar. Eğer istersek şöyle bir görünüm verebiliriz onay kutularımıza:

#!/usr/bin/python
#-*-coding=utf-8-*-
from Tkinter import *
pencere = Tk()
onay_el = Checkbutton(text="elma")
onay_el.pack(side=LEFT)
onay_sa = Checkbutton(text="salatalık")
onay_sa.pack(side=LEFT)
onay_do = Checkbutton(text="domates")
onay_do.pack(side=LEFT)
onay_ka = Checkbutton(text="karnıbahar")
onay_ka.pack(side=LEFT)
mainloop()

Öğeler böyle yan yana dizildiklerinde fena görünmüyorlar, ama biz yine de öğelerin düzgün şekilde alt alta dizilmesini isteyebiliriz. Eğer bu konuda ısrarcıysak bu noktada farklı bir bilgiye ihtiyacımız var.

Bildiğiniz ve gördüğünüz gibi, herhangi bir pencere aracı oluşturduktan sonra "pack" ifadesi yardımıyla pencere aracımızı paketliyorduk. Aslında bu "pack" ifadesi Tkinter'de "Geometri Yöneticisi" denen araçlardan bir tanesidir. Geometri Yöneticileri bir pencere aracının nasıl görüneceğini, nerede duracağını, yani kısaca o aracın şeklini şemalini belirlerler. Mesela "pack" adlı Pencere Yöneticisine, yukarıda gördüğümüz gibi bir "side=LEFT" parametresi eklediğimizde ilgili pencere aracı sola yaslanıyor... Tkinter'de üç adet Geometri Yöneticisi bulunur:

+ Pack Geometri Yöneticisi
+ Grid Geometri Yöneticisi
+ Place Geometri Yöneticisi

Bu Geometri Yöneticilerinin her birinin ayrı özellikleri vardır ve bunların her biri belli bir işlevi yerine getirmede daha başarılıdır. Pack ve Grid Geometri Yöneticileri genel olarak hemen her işi yapmamıza izin verir. O yüzden bu iki Yönetici gayet kullanışlıdır. Place Geometri Yöneticisi ise pencere araçlarını pencere üzerinde yerli yerine oturtma konusunda çok ustadır. O yüzden pencere araçlarını istediğimiz şekilde pencere üzerine konumlandırmak istediğimiz zaman bu işi en kolay Place Geometri Yöneticisi yardımıyla yapabiliriz.

Geometri Yöneticileri ile ilgili olarak aklımızda tutmamız gereken en önemli şey aynı pencere üzerinde birbirinden farklı Yöneticileri bir arada kullanmamaktır... Bunun ne demek olduğunu ilerde örneklerle gösterdiğimiz zaman çok daha iyi anlayacaksınız.

Dediğimiz gibi, pencere araçlarını istediğimiz şekilde dizmek için en uygun geometri yöneticisi "place" adlı olan... Şimdi bununla ilgili bir örnek görelim.. Mesela bir tane onay kutusu oluşturup bunu en sola yaslayalım:

from Tkinter import *
pencere = Tk()
onay = Checkbutton(text="Pardus")
onay.place(relx = 0.0, rely = 0.1)

mainloop()

Gördüğünüz gibi, bu place adlı yönetici de tıpkı pack gibi çalışıyor. Burada dikkatimizi çeken "relx" ve "rely" seçenekleri onay kutusunun koordinatlarını gösteriyor. Buna göre onay kutumuz x düzlemi üzerinde 0.0 konumunda; y düzlemi üzerinde ise 0.1 konumunda yer alıyor. Yani yukarıdan aşağıya 0.0; soldan sağa 0.1 konumunda bulunuyor pencere aracımız.

Hemen Birkaç tane daha onay kutusu ekleyelim:

#!/usr/bin/python
#-*-coding=utf-8-*-
from Tkinter import *
pencere = Tk()
onay_pa = Checkbutton(text="Pardus")
onay_pa.place(relx = 0.0, rely = 0.1)
onay_de = Checkbutton(text="Debian")
onay_de.place(relx = 0.0, rely = 0.2)
onay_ub = Checkbutton(text="Ubuntu")
onay_ub.place(relx = 0.0, rely = 0.3)
onay_wix = Checkbutton(text="Windows XP")
onay_wix.place(relx = 0.0, rely = 0.4)
mainloop()

Dikkat ederseniz yukarıdaki bütün onay kutularının relx seçeneği 0.0 iken, rely seçenekleri birer birer artmış... Bunun nedeni, bütün onay kutularını sola yaslayıp hepsini alt alta dizmek isteyişimiz... Bu örnek relx ve rely seçeneklerinin nasıl kullanılacağı konusunda iyi bir fikir vermiş olmalı. Eğer bir kolaylık sağlayacaksa, relx'i sütun, rely'yi ise satır olarak düşünebilirsiniz.

Şimdi de mesela "Pardus"u "Debian"ın yanına, "Ubuntu"yu da "Windows XP"nin yanına gelecek şekilde alt alta sıralayalım:

#!/usr/bin/python
#-*-coding=utf-8-*-
from Tkinter import *
pencere = Tk()
onay_pa = Checkbutton(text="Pardus")
onay_pa.place(relx = 0.0, rely = 0.1)
onay_de = Checkbutton(text="Debian")
onay_de.place(relx = 0.4, rely = 0.1)
onay_ub = Checkbutton(text="Ubuntu")
onay_ub.place(relx = 0.0, rely = 0.2)
onay_wix = Checkbutton(text="Windows XP")
onay_wix.place(relx = 0.4, rely = 0.2)
mainloop()

Pardus'u 0.0 no'lu sütunun 0.1 no'lu satırına; Debian'ı da 0.4 no'lu sütunun 0.1 no'lu satırına yerleştirdik. Aynı şekilde Ubuntu'yu 0.0 no'lu sütunun 0.2 no'lu satırına; Windows XP'yi de 0.4 no'lu sütunun 0.2 no'lu satırına yerleştirdik.

Eğer oluşturduğumuz bu onay kutularına biraz canlılık katmak istersek, yani mesela kutunun seçili olup olmamasına göre bazı işler yapmak istersek kullanmamız gereken bazı özel kodlar var...

Önce hemen yazmamız gereken ilk satırları yazalım:

#!/usr/bin/env python
#-*-coding:utf-8-*-
from Tkinter import *
pencere = Tk()

Bunun hemen ardından şöyle iki satır ekleyelim:

#!/usr/bin/env python
#-*-coding:utf-8-*-
from Tkinter import *
pencere = Tk()
d = IntVar()
d.set(0)

Burada "d=IntVar()" satırıyla yaptığımız şey "d" adlı bir değişken oluşturup, bunun değeri olarak "IntVar()" ifadesini belirlemek... Peki bu "IntVar()" denen şey de ne oluyor?

IntVar(), İngilizce "Integer Variable" (Sayı Değişkeni) ifadesinin kısaltması. Bu ifade yardımıyla değişken olarak bir sayı belirlemiş oluyoruz. Bunun dışında Tkinter'de kullanacağımız, buna benzer iki ifade daha var: StringVar() ve DoubleVar()

StringVar() yardımıyla karakter dizilerini; DoubleVar() yardımıyla da Ondalık Sayıları (kayan noktalı sayılar – floats) depolayabiliyoruz. Buraya kadar anlattıklarımız biraz bulanık gelmiş olabilir... Ama endişeye hiç gerek yok. d=IntVar() satırının hemen altındaki d.set(0) ifadesi pek çok şeyi açıklığa kavuşturacak. O halde hemen bu satırın anlamını kavramaya çalışalım..

Aslında d = IntVar() ifadesi yardımıyla başladığımız işi tamamlamamızı sağlayan satır bu d.set(0) satırı... Bunun yardımıyla "d=IntVar()" ifadesinin değeri olarak "0"ı seçtik. Yani bu satırı bir onay kutusu için yazdığımızı düşünürsek, onay kutusunun değerini "seçili değil" olarak belirlemiş olduk. Bu iki satırdan sonra oluşturacağımız onay kutusu karşımıza ilk çıktığında işaretlenmemiş olacaktır. Hemen görelim:

#!/usr/bin/env python
#-*-coding:utf-8-*-
from Tkinter import *
pencere = Tk()
d = IntVar()
d.set(0)

btn1 = Checkbutton(text="Pardus", variable=d)
btn1.place(relx=0.0,rely=0.1)

mainloop()

Burada dikkatimizi çeken bir farklılık, "btn1" adlı onay kutusunun "seçenekleri" arasına "variable" adlı bir seçeneğin girmiş olması... Bu seçeneğin işlevini az çok anlamış olmalısınız: Yukarıda belirlediğimiz "d = IntVar()" ve "d.set(0)" ifadeleri ile "Checkbutton" pencere aracı arasında bağlantı kuruyor. Yani bu seçenek yardımıyla pencerece aracına, "değişken olarak d'yi kullan" emrini veriyoruz.

Bu kodları çalıştırdığımızda karşımıza içinde bir onay kutusu bulunan bir pencere açılır. Bu penceredeki onay kutusu "seçilmemiş" haldedir. İsterseniz yukarıdaki kodlar içinde yer alan "d.set(0)" ifadesini "d.set(1)" olarak değiştirip kodlarımızı öyle çalıştıralım:

#!/usr/bin/env python
#-*-coding:utf-8-*-
from Tkinter import *
pencere = Tk()
d = IntVar()
d.set(1)

btn1 = Checkbutton(text="Pardus", variable=d)
btn1.place(relx=0.0,rely=0.1)

mainloop()

Gördüğünüz gibi, bu defa oluşan onay kutusu "seçili" vaziyette... Eğer yukarıdaki kodlar içindeki "d.set()" satırını tamamen kaldırırsak, Tkinter varsayılan olarak d.set() için "0" değerini atayacaktır.

Gelin şimdi bu kodları biraz geliştirelim. Mesela penceremizde bir "Entry" aracı olsun ve onay kutusunu seçtiğimiz zaman bu "Entry" aracında bizim belirlediğimiz bir cümle görünsün... Bu kodlar içinde göreceğimiz ".get" ifadesine aslında pek yabancı sayılmayız. Bunu daha önceden "Entry" aracını kullanırken de görmüştük. Bu ifade yardımıyla bir değişkeninin değerini sonradan kullanmak üzere depolayabiliyoruz. Aşağıdaki örneği dikkatle inceleyin:

#!/usr/bin/python
#-*-coding=utf-8-*-
from Tkinter import *
pencere = Tk()

# Onay kutusu için bir değişken oluşturuyoruz
v = IntVar() 

# Bu değişkene değer olarak "0" atayalım	 
v.set(0)		

# Öbür onay kutusu için başka bir değişken daha oluşturuyoruz
z = IntVar()

# Bu değişkene de "0" değerini atıyoruz.
z.set(0)

# Bu kez bir karakter değişkeni oluşturalım
d = StringVar()

# Bu değişkenin değeri "Pardus" olsun.
d.set("Pardus")

# Bir tane daha karakter değişkeni oluşturalım
e = StringVar()

# Bunun da değeri "Debian" olsun. 
e.set("Debian")

# Şimdi onay kutularını seçili hale getirdiğimizde çalışmasını istediğimiz komut için bir fonksiyon oluşturuyoruz:
def onay():
	# Eğer "v" değişkeninin değeri "1" ise....
	if v.get()==1:
		# d.get() ile "d" değişkeninin değerini alıyoruz...
		giris.insert(0,"Merhaba %s kullanıcısı" %d.get())
		
	# Yok eğer "z" değişkeninin değeri "1" ise...
	elif z.get()==1:
		giris.delete(0,END)
		# e.get() ile "e" değişkeninin değerini alıyoruz...
		giris.insert(0,"Merhaba %s kullanıcısı" %e.get())
	# Değişkenlerin değer "1" değil, başka bir değer ise..."
	else:
		giris.delete(0,END)
		
# Aşağıda "text" seçeneğinin değerinin "d.get()" olduğuna dikkat edin. 
onay_pa = Checkbutton(text=d.get(), variable=v, command=onay)
onay_pa.place(relx = 0.0, rely = 0.1)

# Aşağıda "text" seçeneğinin değerinin "e.get()" olduğuna dikkat edin.
onay_de = Checkbutton(text=e.get(), variable=z, command=onay)
onay_de.place(relx= 0.0, rely= 0.2)

giris = Entry(width=24)
giris.place(relx = 0.0, rely=0.0)
mainloop()  

"Toplevel" Pencere Aracı

Toplevel aracı bizim ana pencere dışında farklı bir pencere daha açmamızı sağlar. Mesela bir ana pencere üstündeki düğmeye bastığınızda başka bir pencere daha açılsın istiyorsanız bu işlevi kullanmanız gerekiyor. En basit kullanımı şöyledir:

#!/usr/bin/python
#-*-coding=utf-8-*-
from Tkinter import *
pencere = Tk()
pencere2 = Toplevel()
mainloop()

Bu kodları çalıştırdığımızda ekranda ikinci bir pencerenin daha açıldığını görürüz.

Diyelim ki bu ikinci pencerenin, bir düğmeye basıldığında açılmasını istiyoruz:

#!/usr/bin/python
#-*-coding=utf-8-*-
from Tkinter import *
pencere = Tk()
def ekle():
	pencere2 = Toplevel()

btn_pen2 = Button(text="ekle", command=ekle)
btn_pen2.pack()

mainloop()

Gördüğünüz gibi pencere2'nin açılışını bir fonksiyona bağladık. Ardından da ana pencere üzerinde btn_pen2 adlı bir düğme oluşturduk ve bu düğmeye "command" seçeneği yardımıyla yukarıda tanımladığımız fonksiyonu atayarak düğmeye basılınca ikinci pencerenin açılmasını sağladık.

Eğer açılan ikinci pencere üzerinde de başka düğmeler olsun istiyorsak şu şekilde hareket etmemiz gerekir:

#!/usr/bin/python
#-*-coding=utf-8-*-
from Tkinter import *
pencere = Tk()
def ekle():
	pencere2 = Toplevel()
	btn_pen = Button(pencere2,text="çıkış", command=pencere2.destroy)
	btn_pen.pack()

btn_pen2 = Button(pencere,text="ekle", command=ekle)
btn_pen2.pack()

mainloop()

Yine gördüğünüz gibi, ilk tanımladığımız ekle fonksiyonu altında bir düğme oluşturduk. Burada yeni bir durum dikkatinizi çekmiş olmalı. Ekle fonksiyonu altında yeni tanımladığımız düğmede ilave olarak "text" seçeneğinden önce bir "pencere2" ifadesini görüyoruz. Bunu yapmamızın nedeni şu: Elimizde "pencere" ve "pencere2" adında iki adet pencere var. Böyle bir durumda oluşturulan pencere aracının hangi pencere üzerinde gösterileceğini Tkinter'e anlatmamız gerekiyor. Sadece bir pencere varken pencereleri açıkça belirtmeye gerek olmuyordu, ama eğer birden pencere var ve siz oluşturulan düğmenin hangi pencere görüntüleneceğini belirtmezseniz, örneğin bizim durumumuzda Tkinter "ekle" adlı düğmeye her basışta otomatik olarak ana pencere üzerinde "çıkış" adlı bir düğme oluşturacaktır. Anladığınız gibi, eğer aksi belirtilmemişse, pencere araçları otomatikman ana pencere üzerinde açılacaktır...

Diyelim ki "a", "b", "c" ve "d" adlarında dört adet penceremiz var. İşte hangi düğmenin hangi pencerede görüntüleneceğini belirlemek için bu özellikten faydalanacağız:

btn1 = Button(a, text="btn1")
btn2 = Button(b, text="btn2")
btn3 = Button(c, text="btn3")
btn4 = Button(d, text="btn4")

yukarıdaki kodlarda yeni bir özellik olarak bir de "command=pencere2.destroy" seçeneğini görüyoruz. Aslında ***.destroy komutu biraz ***.quit komutuna benziyor; görevi mevcut pencereyi kapatmak. Peki burada pencere2.destroy komutu yerine pencere2.quit komutunu kullanamaz mıyız? Tabii ki kullanabiliriz, ancak kullanırsak "çıkış" düğmesine bastığımızda sadece pencere2 değil, doğrudan ana pencerenin kendisi de kapanacaktır. Eğer ikinci pencerenin kapanıp ana pencerenin açık kalmasını istiyorsanız kullanmanız gereken komut ***.destroy; yok eğer ikinci pencere kapandığında ana pencere de kapansın istiyorsanız kullanmanız gereken komut ***.quit olmalıdır.

btn_pen2 adlı düğmeyi ise, "text" seçeneğinin hemen önüne yazdığımız "pencere" ifadesinden de anlayacağınız gibi "pencere" adlı pencerenin üzerine yerleştiriyoruz. Yukarıda bahsettiğimiz gibi burada "pencere" ifadesini kullanmasanız da olur, çünkü zaten Tkinter siz belirtmesiniz de düğmeyi otomatik olarak ana pencere üzerinde açacaktır. Tabii düğmeyi ana pencerede değil de ikincil pencereler üzerinde açmak isterseniz bunu Tkinter'e açıkça söylemeniz gerekir...

"Listbox" Pencere Aracı

Bu araç bize pencereler üzerinde bir "liste içeren kutu" hazırlama imkanı veriyor. Hemen basit bir "Listbox" kullanımı örneği görelim:

liste = Listbox()
liste.pack()

Gördüğünüz gibi, bu aracın da kullanımı öteki araçlardan hiç farklı değil... İsterseniz bu aracı bir de bağlamında görelim:

#!/usr/bin/python
#-*-coding=utf-8-*-
from Tkinter import *
pencere = Tk()
liste = Listbox()
liste.pack()
mainloop()

Bu haliyle pencerenin tamamımını kapladığı için çok belirgin olmayabilir liste kutumuz... Ama pencereye bir de düğme eklersek liste kutusu daha rahat seçilebilir hale gelecektir:

#!/usr/bin/python
#-*-coding=utf-8-*-
from Tkinter import *
pencere = Tk()
liste = Listbox()
liste.pack()

btn = Button(text="ekle")
btn.pack()
mainloop()

Hatta şimdiye kadar öğrendiğimiz başka özellikleri kullanarak daha şık bir görünüm de elde edebiliriz:

#!/usr/bin/python
#-*-coding=utf-8-*-
from Tkinter import *
pencere = Tk()
liste = Listbox(bg="white")
liste.pack()

etiket = Label(text="#####################", fg="magenta", bg="light green")
etiket.pack()

btn = Button(text="ekle",bg="orange",fg="navy")
btn.pack()

etiket2 = Label(text="#####################", fg="magenta", bg="light green")
etiket2.pack()
mainloop()

Tabii ki siz pencere araçlarını ve yaratıcılığınızı kullanarak çok daha çekici görünümler ve renkler elde edebilirsiniz...

Şimdi liste kutumuza bazı öğeler ekleyelim. Bunun için şu basit ifadeyi kullanacağız:

liste.insert(END,"öğe 1")

Tabii ki bunu bu şekilde tek başına kullanamayız. Hemen bu parçacığı yukarıdaki kod içine yerleştirelim:

#!/usr/bin/python
#-*-coding=utf-8-*-
from Tkinter import *
pencere = Tk()
liste = Listbox(bg="white")
liste.insert(END,"öğe 1")
liste.pack()

etiket = Label(text="#####################", fg="magenta", bg="light green")
etiket.pack()

btn = Button(text="ekle",bg="orange",fg="navy")
btn.pack()

etiket2 = Label(text="#####################", fg="magenta", bg="light green")
etiket2.pack()
mainloop()

Gördüğünüz gibi, bu parçacığı, liste kutusunu tanımladığımız satırın hemen altına ekledik. Biz liste kutumuza aynı anda birden fazla öğe de eklemek isteyebiliriz. Bunun için basitçe bir "for döngüsü" kullanabiliriz:

linux_dagitimlari = ["Pardus", "Debian", "Ubuntu", "PclinuxOS", "TruvaLinux", "Gelecek Linux"]

for i in linux_dagitimlari:
        liste.insert(END, i)

Hemen bu kodları da yerli yerine koyalım:

#!/usr/bin/python
#-*-coding=utf-8-*-
from Tkinter import *
pencere = Tk()
liste = Listbox(bg="white")
liste.pack()

linux_dagitimlari = ["Pardus", "Debian", "Ubuntu", "PclinuxOS", "TruvaLinux", "Gelecek Linux"]

for i in linux_dagitimlari:
	liste.insert(END, i)

etiket = Label(text="#################", fg="magenta", bg="light green")
etiket.pack()

btn = Button(text="ekle",bg="orange",fg="navy")
btn.pack()

etiket2 = Label(text="#################", fg="magenta", bg="light green")
etiket2.pack()
mainloop()

Gayet güzel bir liste kutusu oluşturduk ve listemizdeki öğeleri de rahatlıkla seçebiliyoruz... Yalnız dikkat ettiyseniz ana pencere üzerindeki ekle düğmesi şu anda hiçbir işe yaramıyor... Tabii ki onu oraya boşu boşuna koymadık.. Hemen bu düğmeye de bir işlev atayalım... Mesela, bu düğmeye basıldığında ayrı bir pencere açılsın ve kullanıcıdan girdi alarak ana penceredeki liste kutusuna eklesin... Tabii ki bu yeni açılan pencerede de bir giriş kutusu ve bir de işlemi tamamlamak için bir düğme olsun. Hemen işe koyulalım:

#!/usr/bin/python
#-*-coding=utf-8-*-
from Tkinter import *
pencere = Tk()

liste = Listbox(bg="white")
liste.pack()


linux_dagitimlari = ["Pardus", "Debian", "Ubuntu", "PclinuxOS", "TruvaLinux", "Gelecek Linux"]

for i in linux_dagitimlari:
	liste.insert(END, i)
        
def yeni():
        global giris
        pencere2 = Toplevel()
        giris = Entry(pencere2)
        giris.pack()
        btn2 = Button(pencere2, text="tamam",command=ekle)
        btn2.pack()

def ekle():
        liste.insert(END,giris.get())
        giris.delete(0,END)

etiket = Label(text="#################", fg="magenta", bg="light green")
etiket.pack()

btn = Button(text="ekle",bg="orange",fg="navy", command=yeni)
btn.pack()

etiket2 = Label(text="#################", fg="magenta", bg="light green")
etiket2.pack()
mainloop()

İsterseniz daha anlaşılır olması için parça parça ilerleyelim:

#!/usr/bin/python
#-*-coding=utf-8-*-
from Tkinter import *
pencere = Tk()

Bu kısmı zaten biliyoruz... Herhangi bir açıklamaya gerek yok...

liste = Listbox(bg="white")
liste.pack()

linux_dagitimlari = ["Pardus", "Debian", "Ubuntu", "PclinuxOS", "TruvaLinux", "Gelecek Linux"]

for i in linux_dagitimlari:
	liste.insert(END, i)

Bu kısımda bildiğiniz gibi önce "liste" adında bir "liste kutusu" (Listbox) oluşturduk. Liste kutumuzun arkaplan rengini de beyaz olarak belirledik.

Ardından da "linux_dagitimlari" adında bir liste oluşturduk ve tek tek öğelerini yazdık... Hemen alt satırda bir "for döngüsü" yardımıyla linux_dagitimlari adlı listedeki bütün öğeleri "liste" adı verdiğimiz "liste kutusu" içine yerleştirdik.

def yeni():
        global giris
        pencere2 = Toplevel()
        giris = Entry(pencere2)
        giris.pack()
        btn2 = Button(pencere2, text="tamam",command=ekle)
        btn2.pack()

Burada yaptığımız iş basit bir fonksiyon oluşturmaktan ibaret... Önce "yeni" adlı bir fonksiyon oluşturuyoruz. Ardından "pencere2" adıyla ana pencereden ayrı bir pencere daha oluşturuyoruz.. Bu yeni pencere, ileride "ekle" tuşuna bastığımızda açılmasını istediğimiz pencere oluyor... Alt satırda, bu yeni pencere üzerine yerleştirmek için "giris" adlı bir "Entry" pencere aracı oluşturuyoruz. Parantez içine "pencere2" yazmayı unutmuyoruz, çünkü bu "Entry" aracının oluşmasını istediğimiz yer ikinci pencere... Dikkat ettiyseniz fonksiyonu tanımlarken "global giris" adlı bir satır daha ekledik... Bu satırın amacı, fonksiyon içindeki "giris" adlı "Entry" aracını fonksiyon dışında da kullanabilmek... Çünkü bu "Entry" aracı bize daha sonra da lazım olacak... "Entry" aracına benzer şekilde bir de "btn2" adıyla bir düğme oluşturuyoruz. Bunu da ikinci penceremize yerleştiriyor, adını "tamam" koyuyor ve komut olarak aşağıda tanımlayacağımız "ekle" fonksiyonunu seçiyoruz.

def ekle():
        liste.insert(END,giris.get())
        giris.delete(0,END)

İşte bu parçada da "ekle" adlı bir fonksiyon oluşturduk. Burada "liste.insert" ifadesi "liste" adlı "liste kutusuna" ekleme yapmamızı sağlıyor. Parantez içindeki "giris.get()" ifadesi size tanıdık geliyor olmalı.. Çünkü aynı ifadeyi "Entry" pencere aracını anlatırken de görmüştük... Hatırlarsanız bu ifade sayesinde "Entry" aracına kullanıcı tarafından girilen verileri daha sonra kullanmak amacıyla elimize tutabiliyorduk... İşte burada da bu ifade yardımıyla "giris" adlı "Entry" pencere aracının içeriğini alıp "liste" adlı "liste kutusu" içine yerleştiriyoruz. Alt satırdaki "giris.delete(0,END)" ifadesi ise "Entry" aracına kullanıcı tarafından giriş yapıldıktan sonra kutunun boşaltılmasını sağlıyor.

etiket = Label(text="#################", fg="magenta", bg="light green")
etiket.pack()

btn = Button(text="ekle",bg="orange",fg="navy", command=yeni)
btn.pack()

etiket2 = Label(text="#################", fg="magenta", bg="light green")
etiket2.pack()
mainloop()

Bu son parçada bilmediğimiz hiçbir şey yok... Normal bir şekilde "etiket" adı verdiğimiz "Label" aracını tanımlıyoruz... Burada "Label" aracını süsleme amacıyla nasıl kullandığımıza dikkat edin.... "fg" ve "bg" seçeneklerini de önceki bölümlerden hatırlıyoruz. "fg" önplandaki rengi; "bg" ise arkaplandaki rengi seçmemizi sağlıyor. "magenta" ve "light green" ise kullanacağımız renklerin adları oluyor. Bunun altında ise basit bir "Button" aracı tanımlıyoruz. İsmini ve renklerini belirledikten sonra da "command" seçeneği yardımıyla yukarıda tanımladığımız "yeni" adlı fonksiyonu bu düğmeye bağlıyoruz. Bunun aşağısındaki "etiket2"nin ise "etiket" adlı araçtan hiçbir farkı yok...

Kodlarımızı çalıştırdığımızda karşımıza gayet hoş, üstelik güzel de bir işlevi olan bir pencere çıkıyor. Burada "ekle" düğmesine bastığımızda karşımıza yeni bir pencere açılıyor. Bu yeni pencerede, kullanıcının giriş yapabilmesi için bir "Entry" aracı, bir de işlemi tamamlayabilmesi için "Button" aracı yer alıyor. Kullanıcı "Entry" aracına bir veri girip "tamam" düğmesine bastığında "Entry" aracına girilen veri ana penceredeki "liste kutusu"na ekleniyor... Ayrıca ilk veri girişinin ardından "Entry" aracı içindeki alan tamamen boşaltılıyor ki kullanıcı rahatlıkla ikinci veriyi girebilsin... Çok hoş değil mi?!

Siz de burada kendinize göre değişiklikler yaparak özellikle ikinci pencereyi göze daha hoş görünecek bir hale getirebilirsiniz...

Burada dikkat ederseniz, ikinci pencerede, giriş kutusuna hiçbir şey yazmadan "tamam" düğmesine basarsak ana penceredeki liste kutusuna boş bir satır ekleniyor. Şimdi öyle bir kod yazalım ki, kullanıcı eğer ikinci penceredeki giriş kutusuna hiçbir şey yazmadan "tamam" düğmesine basarsa giriş kutusu içinde "Veri Yok!" yazısı belirsin ve bu yazı ana penceredeki liste kutusuna eklenmesin:

Bunun için kodlarımız içindeki "ekle" fonksiyonuna iki adet "if" koşulu eklememiz gerekiyor...

def ekle():
	if not giris.get():
		giris.insert(END,"Veri Yok!")
	if giris.get() != "Veri Yok!":
		liste.insert(END,giris.get())
		giris.delete(0,END)

Gördüğünüz gibi "giris" boşken "tamam" tuşuna basıldığında "Veri Yok!" ifadesi ekrana yazdırılıyor... Ancak burada şöyle bir problem var: Eğer "Veri Yok!" ifadesi ekrana yazdırıldıktan sonra kullanıcı bu ifadeyi silmeden bu ifadenin yanına bir şeyler yazıp "tamam"a basarsa "Veri Yok!" ifadesiyle birlikte o yeni yazdığı şeyler de listeye eklenecektir... Bunu engellemek için kodumuzu şu hale getirebiliriz:

def ekle():
	if not giris.get():
		giris.insert(END,"Veri Yok!")
	if not "Veri Yok!" in giris.get():
		liste.insert(END,giris.get())
		giris.delete(0,END)

Yani şöyle demiş oluyoruz bu ifadelerle:

Eğer "giris" adlı "Entry" aracı boş ise, araç içinde "Veri Yok!" ifadesini göster. 
Eğer "giris" adlı "Entry" aracı içinde "Veri Yok!" ifadesi bulunmuyorsa, "liste" adlı "Listbox" aracına "giris" içindeki bütün veriyi yazdır... 

Liste kutumuza öğelerimizi ekledik... Peki bu öğeleri silmek istersek ne yapacağız?

Niyetimiz liste kutusundan öğe silmek olduğunu göre en başta bir silme düğmesi oluşturmamız mantıklı olacaktır:

btn_sil = Button()
btn_sil.pack()

Bu düğmenin bir iş yapabilmesi için de bu düğmeye bir fonksiyon atamamız gerekir:

def sil():
        liste.delete(ACTIVE)

Burada gördüğünüz gibi, silme işlemi için "liste.delete" ifadesini kullanıyoruz... Parantez içindeki "ACTIVE" ifadesi ise liste kutusu içinden bir seçim yapıp "sil" düğmesine basınca bu seçili öğenin silinmesini sağlayacak... Yani "aktif" olan öğe silinecek. Bu iki parçayı öteki komutlarla birlikte bir görelim bakalım:

#!/usr/bin/python
#-*-coding=utf-8-*-
from Tkinter import *
#!/usr/bin/python
#-*-coding=utf-8-*-
from Tkinter import *
pencere = Tk()

liste = Listbox(bg="white")
liste.pack()


linux_dagitimlari = ["Pardus", "Debian", "Ubuntu", "PclinuxOS", "TruvaLinux", "Gelecek Linux"]

for i in linux_dagitimlari:
	liste.insert(END, i)
        
def yeni():
	global giris
	pencere2 = Toplevel()
	giris = Entry(pencere2)
	giris.pack()
	btn2 = Button(pencere2, text="tamam",command=ekle)
	btn2.pack()

def ekle():
	if not giris.get():
		giris.insert(END,"Veri Yok!")
	if not "Veri Yok!" in giris.get():
		liste.insert(END,giris.get())
		giris.delete(0,END)

def sil():
        liste.delete(ACTIVE)

etiket = Label(text="#################", fg="magenta", bg="light green")
etiket.pack()

btn = Button(text="ekle",bg="orange",fg="navy", command=yeni)
btn.pack()

btn_sil = Button(text="sil",bg="orange", fg="navy",command=sil)
btn_sil.pack()

etiket2 = Label(text="#################", fg="magenta", bg="light green")
etiket2.pack()
mainloop()

Tabii ki, sil düğmesinin görünüşünü pencere üzerindeki öteki öğelere uydurmak için "fg" ve "bg" seçenekleri yardımıyla ufak bir renk ayarı yapmayı da unutmadık...

Böylece bir pencere aracını daha bitirmiş olduk... Gelelim sıradaki pencere aracımıza:

"Menu" Pencere Aracı

Adından da anlaşılacağı gibi bu araç bize pencerelerimiz üzerinde menüler hazırlama olanağı sağlıyor... "Menu" pencere aracının kullanımı öteki araçlardan birazcık daha farklıdır, ama kesinlikle zor değil... Hemen küçücük bir menü hazırlayalım:

Önce standart satırlarımızı ekliyoruz:

#!/usr/bin/env python
#-*-coding:utf-8-*-
from Tkinter import *
pencere = Tk()

Şimdi menümüzü oluşturmaya başlayabiliriz...

menu = Menu(pencere)

Burada "menu" adlı bir "Menu pencere aracı" oluşturduk... Adı "menu" olmak zorunda değil... Siz istediğiniz ismi kullanabilirsiniz... Ama tabii ki pencere aracımızın adı olan "Menu"yu değiştiremeyiz... Buraya kadar öteki pencere araçlarından hiçbir farkı yok...

Parantez içindeki "pencere" ifadesinden de anladığımız gibi, bu pencere aracını ana pencere üzerinde oluşturuyoruz. Hatırlayacağınız gibi burada "pencere" diye açık açık belirtmesek de Tkinter pencere aracımızı otomatik olarak ana pencere üzerinde oluşturacaktır. Aslında bu satır yardımıyla ana pencerenin en üstünde, sonradan gelecek menüler için bir "menü çubuğu" oluşturmuş oluyoruz.

pencere.config(menu=menu)
dosya = Menu(menu)

Burada "config" metodu yardımıyla öncelikle "menu" adlı aracı "pencere"ye bağlıyoruz. Parantez içindeki ilk "menu" ifadesi, tıpkı öteki pencere araçlarında gördüğümüz "text" ifadesi gibi bir "seçenek"... ikinci "menu" ifadesi ise yukarıda bizim "Menu" aracına kendi verdiğimiz isim... Bu isim herhangi bir kelime olabilirdi... Yani en başta menünün adını "kepap" olarak belirleseydik, burada "menu=kebap" da diyebilirdik...

İkinci satırda ise "dosya" adlı başka bir "Menu pencere aracı" daha oluşturuyoruz. Hatırlarsanız ilk Menu aracını oluştururken parantez içine "pencere" yazarak aracı pencereye bağlamıştık. Bu kezse aracımızı bir önceki "menu"nün üzerinde oluşturuyoruz... Aslında bu satır yardımıyla bir önceki aşamada oluşturduğunuz "araç çubuğu" üzerinde "iner menü" (drop-down menu) için bir yer açmış oluyoruz.

menu.add_cascade(label="Dosya",menu=dosya)

Şimdi yapmamız gereken, menünün aşağıya doğru açılmasını yani "inmesini" sağlamak. Bu iş için yukarıda gördüğünüz "add_cascade" metodunu kullanıyoruz. Bu metodun "menu" adlı "menü araç çubuğuna" bağlı olduğuna dikkat edin. Parantez içinde gördüğümüz "label" ifadesi de tıpkı "text" gibi, menüye ad vermemizi sağlıyor. Menümüzün adını "Dosya" olarak belirledik. Parantez içindeki diğer ifade olan "menu" de "Dosya"nın hangi "araç çubuğu" üzerinde üzerinde oluşturulacağını gösteriyor...

dosya.add_command(label="Aç")
dosya.add_command(label="Kaydet")
dosya.add_command(label="Farklı Kaydet...")
dosya.add_command(label="Çıkış",command=pencere.quit)

mainloop()

Burada gördüğümüz ifadeler ise bir üstte oluşturduğumuz "Dosya" adlı menünün alt başlıklarını oluşturmamızı sağlıyor... Burada "add_command" metotlarının "dosya" adlı araç çubuğuna bağlandığına dikkat edin... Bu satırlardan anladığınız gibi, "Dosya" adlı menümüzün altında "Aç", "Kaydet", "Farklı Kaydet..." ve "Çıkış" gibi alt başlıklar olacak...

Şimdi kodlarımızın hepsini birlikte görelim:

#!/usr/bin/env python
#-*-coding:utf-8-*-

from Tkinter import *

pencere = Tk()

menu = Menu(pencere)

pencere.config(menu=menu)
dosya = Menu(menu)

menu.add_cascade(label="Dosya",menu=dosya)

dosya.add_command(label="Aç")
dosya.add_command(label="Kaydet")
dosya.add_command(label="Farklı Kaydet...")
dosya.add_command(label="Çıkış",command=pencere.quit)

mainloop()

Bu kodları çalıştırdığınızda gayet güzel bir pencere elde etmiş olacaksınız... Yalnız dikkat ettiyseniz, "Dosya"ya bastıktan sonra açılan alt menünün en üstünde "----------" gibi bir şey görüyoruz... Oraya tıkladığımızda ise bütün menü içeriğinin tek bir grup halinde toplanıp ayrı bir pencere oluşturduğunu görüyoruz... Eğer bu özellikten hoşlanmadıysanız, bu minik çizgileri kodlar arasına "tearoff=0" ifadesini ekleyerek yok edebilirsiniz ("tearoff=0" ifadesini "dosya" adlı değişkeni oluştururken ekliyoruz...):

#!/usr/bin/env python
#-*-coding:utf-8-*-

from Tkinter import *

pencere = Tk()

menu = Menu(pencere)
pencere.config(menu=menu)

dosya = Menu(menu, tearoff=0)
menu.add_cascade(label="Dosya",menu=dosya)
dosya.add_command(label="Aç")
dosya.add_command(label="Kaydet")
dosya.add_command(label="Farklı Kaydet...")
dosya.add_command(label="Çıkış",command=pencere.quit)

mainloop()

Konu belki biraz karışık gelmiş olabilir... Ama aslında hiç de öyle değil... İşin mantığını anlamak için yukarıdaki kodlarda geçen şu satırlar bize epeyce yardımcı olabilir:

menu = Menu(pencere)
dosya = Menu(menu, tearoff=0)
menu.add_cascade(label="Dosya",menu=dosya)

Dikkat ettiyseniz, önce "Menu pencere aracını" oluşturuyoruz. Bu araç ilk oluşturulduğunda, parantez içi ifadeden anladığımız gibi, "pencere" adlı ana pencere üzerine bağlanıyor...

İkinci satır vasıtasıyla ikinci kez bir "Menu pencere aracı" oluştururken ise, parantez içi ifadeden anlaşıldığı gibi, oluşturduğumuz menüyü bir önceki "Menu pencere aracı"na bağlıyoruz.

Üçüncü satırda "inen menü"yü oluştururken de, bunu bir önceki "Menu pencere aracı" olan "dosya"ya bağlıyoruz...

Menülere başka alt menüler de eklerken bu mantık çok daha kolay anlaşılıyor... Şöyle ki:

#!/usr/bin/env python
#-*-coding:utf-8-*-

from Tkinter import *

pencere = Tk()

menu = Menu(pencere)
pencere.config(menu=menu)

dosya = Menu(menu, tearoff=0)
menu.add_cascade(label="Dosya",menu=dosya)
dosya.add_command(label="Aç")
dosya.add_command(label="Kaydet")
dosya.add_command(label="Farklı Kaydet...")
dosya.add_command(label="Çıkış",command=pencere.quit)

yeni = Menu(dosya,tearoff=0)
dosya.add_cascade(label="Yeni",menu=yeni)
yeni.add_command(label="Metin Belgesi")
yeni.add_command(label="Resim Dosyası")
yeni.add_command(label="pdf dokümanı")

mainloop()

Gördüğünüz gibi, bu kez "Menu pencere aracımızı" ilk olarak "dosya" adlı araç üzerine bağlıyoruz. Çünkü yeni pencere aracımız, bir önceki pencere aracı olan "dosya"nın üzerinde oluşturulacak. Bir sonraki satırda "add_command" metodunu kullanırken de alt menüleri "yeni" adlı "Menu pencere aracı" üzerine bağlıyoruz... Çünkü bu alt menüler "yeni"nin içinde yer alacak...

Aynı şekilde eğer "Dosya" başlığının yanına bir de mesela "Düzen" diye bir seçenek eklemek istersek şöyle bir bölüm ekliyoruz kodlarımız arasına:

#!/usr/bin/env python
#-*-coding:utf-8-*-

from Tkinter import *

pencere = Tk()

menu = Menu(pencere)
pencere.config(menu=menu)

dosya = Menu(menu, tearoff=0)
menu.add_cascade(label="Dosya",menu=dosya)
dosya.add_command(label="Aç")
dosya.add_command(label="Kaydet")
dosya.add_command(label="Farklı Kaydet...")
dosya.add_command(label="Çıkış",command=pencere.quit)

yeni = Menu(dosya,tearoff=0)
dosya.add_cascade(label="Yeni",menu=yeni)
yeni.add_command(label="Metin Belgesi")
yeni.add_command(label="Resim Dosyası")
yeni.add_command(label="pdf dokümanı")

dosya2 = Menu(menu,tearoff=0)
menu.add_cascade(label="Düzen",menu=dosya2)
dosya2.add_command(label="Bul")

mainloop()

"Text" Pencere Aracı

Şimdiye kadar bir pencerenin sahip olması gereken pek çok özelliği gördük. Hatta pencerelerimize menüler dahi ekledik... Bütün bunların dışında öğrenmemiz gereken çok önemli bir pencere aracı daha var. O da, "Text" adlı pencere aracıdır.. Bu araç sayesinde birden fazla satır içeren metinler oluşturabileceğiz. En basit haliyle "Text" adlı pencere aracını şu şekilde oluşturabiliriz:

#!/usr/bin/env python
#-*-coding:utf-8-*-

from Tkinter import *

pencere = Tk()
metin = Text()
metin.pack()

mainloop()

Oluşturduğumuz bu "Text" aracı pek çok işlevi yerine getirebilecek durumdadır: Bu araç içine şu haliyle istediğimiz uzunlukta metin girebiliriz, klavye ve fareyi kullanarak metni yönetebiliriz, hatta oluşturduğumuz bu "Text" aracını oldukça basit bir "metin editörü" olarak da kullanabiliriz.

Eğer oluşturduğumuz bu "Text" aracı içine öntanımlı olarak herhangi bir metin yerleştirmek istersek şu kodu kullanmamız gerekir:

#!/usr/bin/env python
#-*-coding:utf-8-*-

from Tkinter import *

pencere = Tk()

metin = Text(fg = "blue",font="Helvetica 13 bold")
metin.insert(END,"Sürüm 0.1.1")
metin.pack()

mainloop()

Gördüğünüz gibi, "Text" aracını oluştururken, önceki yazılarda öğrendiğimiz şekilde "fg" seçeneği yardımıyla metni mavi yaptık. "font" seçeneği yardımıyla ise yazı tipini, "Helvetica, 13, koyu ve altı çizili" olarak belirledik.

Kodlarımız içinde kullandığımız "metin.insert" ifadesi de bize öntanımlı bir metin girme imkanı sağladı. Parantez içinde belirttiğimiz "END" ifadesi öntanımlı olarak yerleştireceğimiz metnin pencere aracının neresinde yer alacağını gösteriyor.

Yukarıda verdiğimiz kodu değiştirerek isterseniz daha çekici bir görünüm de elde edebilirsiniz:

#!/usr/bin/env python
#-*-coding:utf-8-*-

from Tkinter import *

pencere = Tk()

a= "Sürüm 0.1.1"

metin = Text(bg="orange",fg = "blue",font="Helvetica 13 bold")
metin.insert(END,a.center(112,"*"))
metin.pack()

mainloop()

Eğer bir metin içinden herhangi bir bölümü almak isterseniz kullanmanız gereken şey "get" ifadesidir. Bu "get" ifadesinin nasıl kullanıldığını görelim şimdi:

#!/usr/bin/env python
#-*-coding:utf-8-*-

from Tkinter import *

pencere = Tk()

metin = Text()
metin.pack()

metin.get(1.0,END)

mainloop()

Yukarıdaki örneği sadece "get" ifadesinin nasıl kullanıldığını göstermek için verdik... Şu haliyle bu kod bizim beklentilerimizi karşılayamaz... Çünkü "get" ifadesi yardımıyla metni aldık, ama aldığımız bu metni kullanmamızı sağlayacak araçları henüz penceremize yerleştirmediğimiz için "get" ifadesinin bize sağladığı işlevi kullanamıyoruz. Şimdilik burada şuna dikkat edelim: "metin.get()" gibi bir ifade kullanırken parantez içinde belirttiğimiz ilk sayı 1.0. Bu rakam metin kutusunun ilk satırının ilk sütununa işaret ediyor. Burada ilk satırın 1'den; ilk sütunun ise 0'dan başladığına dikkat edelim. Virgülden sonra gelen "END" ifadesi ise "Text" aracı içindeki metnin en sonuna işaret ediyor. (İngilizce'de "END" kelimesi "SON" anlamına geliyor). Yani bu koda göre "get" ifadesi yardımıyla Text aracı içindeki bir metni, en başından en sonuna kadar alabiliyoruz. İsterseniz parantez içinde farklı sayılar belirterek, alınacak metnin ilk ve son konumlarını belirleyebiliriz. Mesela şu koda bir bakalım:

#!/usr/bin/env python
#-*-coding:utf-8-*-

from Tkinter import *

pencere = Tk()

metin = Text()
metin.pack()

metin.get(1.0,1.5)

mainloop()  

Burada ise "Text" aracının birinci satırı ve birinci sütunundan, birinci satırı ve beşinci sütununa kadar olan aralıktaki metin alınacaktır.

Şimdi henüz hiçbir iş yapmayan bu kodları biraz işlevli bir hale getirelim:

#!/usr/bin/env python
#-*-coding:utf-8-*-

from Tkinter import *

pencere = Tk()

def al():
	a = metin.get(1.0,END)
	giris.insert(0, a)
	
metin = Text()
metin.pack()

btn = Button(text="al", command=al)
btn.pack()

giris = Entry()
giris.pack()

mainloop() 

Burada öncelikle "Text" aracı içindeki metnin tamamını alıp (metin.get(1.0,END)) "giris" adlı pencere aracına yerleştiren (giris.insert(0,a)) bir fonksiyon oluşturduk. Dikkat ederseniz kullanım kolaylığı açısından "metin.get(1.0,END)" ifadesini "a" adlı bir değişkene atadık.

Daha sonra "metin" adlı "Text" aracımızı ve "btn" adlı "Button" aracımızı oluşturduk. "Button" aracımıza "komut" (command) olarak yukarıda tanımladığımız fonksiyonu göstererek "Button" ile fonksiyon arasında ilişki kurduk.

En sonunda da "giris" adlı "Entry" aracımızı tamamlayarak kodumuzu sona erdirdik.

Bu kodları çalıştırdığımızda karşımıza çıkan boş metin kutusuna herhangi bir şey yazıp alttaki düğmeye basınca, metin kutusunun bütün içeriği düğmenin hemen altındaki küçük metin kutusuna işlenecektir.

Şimdi daha karmaşık bir örnek yapalım:

Aşağıdaki örneği dikkatlice inceleyin:

#!/usr/bin/env python
#-*-coding:utf-8-*-

from Tkinter import *

pencere = Tk()

def al():
	metin2.insert(END,metin.get(2.0,END))
	
a= "Sürüm 0.1.1"

metin = Text(height=15,bg="black",fg = "white",font="Helvetica 13 bold")
metin.insert(END,a.center(112,"*"))
metin.pack()

metin2 = Text(height=15,width=115, bg="light blue",fg="red")
metin2.pack()

btn = Button(text="al",command=al)
btn.pack()

mainloop()

Yukarıdaki kodlarda bir metni ve pencere araçlarını nasıl biçimlendirdiğimize dikkat edin. Ayrıca Python'da karakter dizilerine ait bir metot olan "center" yardımıyla bir kelimenin soluna ve sağına nasıl başka karakterler yerleştirdiğimizi inceleyin. Bu kodlar içinde kendinize göre bazı denemeler yaparak neyin ne işe yaradığını daha iyi anlayabilirsiniz.

Yukarıda bahsettiğimiz "metnin koordinatlarını verme" yöntemi her zaman tercih edilecek bir durum değildir... Ne de olsa kullanıcılarınızdan satır/sütun saymasını bekleyemezsiniz! Herhalde bu gibi durumlarda en iyi yöntem "seçilen metnin alınması" olacaktır. Bunu da basitçe şu kodlar yardımıyla yapıyoruz:

metin.get("sel.first","sel.last")

Burada "sel.first" ifadesi "seçimin başlangıç noktasını"; "sel.last" ifadesi ise "seçimin bitiş noktasını" gösteriyor.

Şimdi bu kod parçasını bir bağlam içinde kullanalım:

#!/usr/bin/env python
#-*-coding:utf-8-*-

from Tkinter import *

pencere = Tk()

def al():
	a = metin.get("sel.first","sel.last")
	metin2.insert(END,a)

metin = Text(height=10,width=35,bg="white",fg = "blue",font="Helvetica 13 bold")
metin.pack()

metin2 = Text(height=10,width=50, bg="black",fg="white")
metin2.pack()

btn = Button(text="al",command=al)
btn.pack()

mainloop()

Bu kodları çalıştırdığımızda, üstteki kutuya yazdığımız metnin istediğimiz bir kısmını seçtikten sonra alttaki düğmeye basarsak, seçili kısım ikinci kutuya işlenecektir.

"Bitmap" Pencere Aracı

Bu pencere aracı ile düğme, etiket, metin veya şekillerinize nokta tabanlı resimler ekleyebilirsiniz. Bitmap (nokta tabanlı) yükleyici sadece X11 bitmap dosyalarını destekler. Diğer tür resimler için PhotoImage aracını öğrenmeniz gerekecek.

X11 nokta esaslı resimler, yükseklik, en ve noktaları içeren bir dizi içeren C dilinde yazılmış bir bölüm içerir. Biliyoruz ki Python içine çeşitli dilleri yazabiliyoruz. Bu bölüm 3 tırnaklı (""") string içine alınabileceği gibi herhangi bir metin dosyasından da okunabilir.

noktalar = """
#define pardus_width 32
#define pardus_height 32
static unsigned char pardus_bits[] = {
   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
   0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0xff, 0x80, 0x03, 0x00,
   0xc3, 0xc0, 0x03, 0x00, 0xc3, 0x80, 0xff, 0x3f, 0xc3, 0xc0, 0xfd, 0x6f,
   0xc3, 0x00, 0xfc, 0xcf, 0xc3, 0x00, 0xfc, 0x0f, 0xc3, 0x00, 0x1c, 0x0f,
   0xc3, 0x00, 0x16, 0x19, 0xff, 0x00, 0x12, 0x11, 0xff, 0x00, 0x02, 0x01,
   0x03, 0x00, 0x00, 0x00, 0xfb, 0xbe, 0x27, 0xfa, 0x8b, 0xa2, 0x28, 0x0a,
   0x8b, 0xa2, 0x28, 0x0a, 0x8b, 0xa2, 0x28, 0x0a, 0x8b, 0xa2, 0x28, 0x0a,
   0xfb, 0xbe, 0x28, 0xfa, 0x8b, 0x8a, 0x28, 0x82, 0x8b, 0x92, 0x28, 0x82,
   0x8b, 0xa2, 0x28, 0x82, 0x8b, 0xa2, 0x28, 0x82, 0x8b, 0xa2, 0x28, 0x82,
   0x8b, 0xa2, 0xe7, 0xfb, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
"""

Nokta esaslı resimler yapmak için herhangi bir bitmap düzenleyici kullanabilir ya da resminizi bir şekilde bitmap türüne çevirebilirsiniz. Örneğin yukarda ben "bitmap" isimli yazılımı kullandım. Nokta tabanlı resmimiz hazır. Bundan sonra ne yapacağız derseniz, cevap resmimizi yazılımımıza tanıtmak olacaktır. Bunu da şu şekilde yapıyoruz :

bitmap = BitmapImage(data=noktalar)

Yukarıda kaynak olarak stringimizi kullanıyor.

bitmap = BitmapImage(file="noktalar")

Eğer stringimizin yerine string içeriğinin kayıtlı olduğu noktalar adında bir dosyamız olsaydı, o dosyayı çağırmak için bu şekilde bir yol izleyecektik.

Nokta temelli resimlerde öntanımlı olarak önalan renkleri siyah, arkaalan renkleri saydamdır. Bunun önüne geçmek için foreground ya da background tercihleri kullanılabilir.

bitmap = BitmapImage(
    data=noktalar,
    foreground="yellow", background="brown"
    )

Yukarıda normalde siyah olan rengimizi sarı, siyah olan rengimizi de kahverengi yaptık.

Peki bu resimleri herhangi bir düğmede, etikette, vs.de kullanmak için ne yapacağız? Çözüm gayet basit. Örneğin bir düğmeye resmimizi eklemek için :

dugme = Button(image=bitmap)
dugme.pack()

Böylece üzerinde Pardus yazısı ve Pardus'a benzetilmeye çalışılan bir resim olan bir düğmemiz oldu.


Önceki Bölüm: Tkinter'le Arayüz Programlama // Temel Bilgiler
Sonraki Bölüm: Nesne Tabanlı Programlama


Bu yazı Programlama bölümünün bir parçasıdır.