4. Pencere Araçları (Widgets) – 2. Bölüm¶
4.1. “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. Burada geometri yöneticilerinden biri olan place() adlı olanı tercih edebiliriz... Ş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="Kubuntu")
onay.place(relx = 0.0, rely = 0.1)
mainloop()
Bir önceki bölümde öğrendiğimizi place() yöneticisini nasıl kullandığımızı görüyorsunuz. Bu yöneticinin “relx” ve “rely” seçenekleri yardımıyla onay kutusunun koordinatlarını belirliyoruz. Buna göre onay kutumuz x düzlemi üzerinde 0.0 konumunda; y düzlemi üzerinde ise 0.1 konumunda yer alıyor. Yani soldan sağa 0.0; yukarıdan aşağıya 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="Kubuntu")
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 “Kubuntu”yu “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="Kubuntu")
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()
Kubuntu’yu 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="Kubuntu", 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="Kubuntu", 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 "Kubuntu" olsun.
d.set("Kubuntu")
# 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()
4.2. “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...
4.3. “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:
gnulinux_dagitimlari = ["Pardus", "Debian", "Ubuntu", "PclinuxOS",
"TruvaLinux", "Gelecek Linux"]
for i in gnulinux_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()
gnulinux_dagitimlari = ["Pardus", "Debian", "Ubuntu", "PclinuxOS",
"TruvaLinux", "Gelecek Linux"]
for i in gnulinux_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()
gnulinux_dagitimlari = ["Pardus", "Debian", "Ubuntu", "PclinuxOS",
"TruvaLinux", "Gelecek Linux"]
for i in gnulinux_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()
gnulinux_dagitimlari = ["Pardus", "Debian", "Ubuntu", "PclinuxOS",
"TruvaLinux", "Gelecek Linux"]
for i in gnulinux_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 “gnulinux_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 gnulinux_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 *
pencere = Tk()
liste = Listbox(bg="white")
liste.pack()
gnulinux_dagitimlari = ["Pardus", "Debian", "Ubuntu", "PclinuxOS",
"TruvaLinux", "Gelecek Linux"]
for i in gnulinux_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:
4.5. “Text” Pencere Aracı¶
Şimdiye kadar bir pencerenin sahp 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ştrduğ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.
4.6. “Scrollbar” Pencere Aracı¶
Scrollbar adlı pencere aracı, Tkinter ile yazdığımız uygulamalara kaydırma çubuğu ekleme imkanı veriyor. Bu pencere aracının özelliği, öteki pencere araçlarının aksine tek başına kullanılmamasıdır. Kaydırma çubuğu kavramının mantığı gereği, bu pencere aracını başka pencere araçları ile birlikte kullanacağız. Mesela “Text” pencere aracılığıyla bir metin kutusu oluşturmuş isek, şimdi öğreneceğimiz “Scrollbar” adlı pencere aracı sayesinde bu metin kutusuna bir kaydırma çubuğu ekleyebileceğiz. İsterseniz hemen ufak bir örnek yapalım:
#!/usr/bin/env python
#-*-coding:utf-8-*-
from Tkinter import *
pencere = Tk()
Buraya kadar olan kısımda bir yenilik yok. Artık ezbere bildiğimiz komutlar bunlar... Devam ediyoruz:
kaydirma = Scrollbar(pencere)
kaydirma.pack(side=RIGHT,fill=Y)
Gördüğünüz gibi, “Scrollbar” adlı pencere aracımızı oluşturup, bunu “pack” yöneticisiyle paketledik. pack() içindeki argümanlara dikkat edin. “side=RIGHT” ifadesi yardımıyla kaydırma çubuğumuzu sağa yaslarken, “fill=Y” ifadesi yardımıyla da Y düzlemi üzerinde (yani yukarıdan aşağıya doğru) boylu boyunca uzatıyoruz. Devam edelim:
metin = Text(yscrollcommand=kaydirma.set)
metin.pack()
Kaydırma çubuğunu bir metin kutusu içinde kullanacağımız için, “Text” pencere aracı vasıtasıyla metin kutumuzu tanımlıyoruz. Burada, “yscrollcommand=kaydirma.set” gibi bir ifade kullandığımıza dikkat edin. Bu ifade ile kaydırma işlemini etkinleştiriyoruz. Şimdi son darbeyi vurabiliriz:
kaydirma.config(command=metin.yview)
mainloop()
Burada “kaydirma.config()” satırını, metin aracını tanımladıktan sonra yazmamız önemli. Eğer metin aracını tanımlamadan config satırını yazarsak komut satırında hataların uçuştuğunu görürüz...
Dilerseniz yukarıda parça parça verdiğimiz uygulamayı bir de topluca görelim:
#!/usr/bin/env python
#-*-coding:utf-8-*-
from Tkinter import *
pencere = Tk()
kaydirma = Scrollbar(pencere)
kaydirma.pack(side=RIGHT,fill=Y)
metin = Text(yscrollcommand=kaydirma.set)
metin.pack()
kaydirma.config(command=metin.yview)
mainloop()
Böylece metin kutusuna yazdığımız yazılar aşağıya doğru uzadıkça sağ tarafta bir kaydırma çubuğu görüntülenecektir.
Peki kaydırma çubuğunun, ekranın alt tarafında görünmesini istersek ne olacak? Yani yukarıdaki örnekte yaptığımız gibi, aşağıya doğru giden metinleri değil de, yana doğru giden metinleri kaydırmak istersek ne yapacağız? Çok kolay. Adım adım gidelim yine:
#!/usr/bin/env python
#-*-coding:utf-8-*-
from Tkinter import *
pencere = Tk()
...devam ediyoruz...
kaydirma = Scrollbar(pencere, orient=HORIZONTAL)
kaydirma.pack(side=BOTTOM,fill=X)
Gördüğünüz gibi, kaydırma çubuğunun pozisyonunu belirlemek için yeni bir seçenekten yararlanıyoruz. Bu yeni seçeneğin adı “orient”. Buna vermemiz gereken değer ise “HORIZONTAL”. Bu İngilizce kelime Türkçe’de “yatay” anlamına geliyor. Kaydırma çubuğumuz ekranda düşey değil, yatay vaziyette görüneceği için bu seçeneği kullandık. Ayrıca “pack” parametrelerine de dikkat edin. “side” seçeneğine “BOTTOM” değerini verdik. Çünkü kaydırma çubuğumuzun ekranın alt tarafında görünmesini istiyoruz. Bir önceki örnekte, çubuğun ekranın sağında görünmesini istediğimiz için “side=RIGHT” şeklinde bir kullanım benimsemiştik (“RIGHT” kelimesi “sağ” anlamına gelirken, “BOTTOM” kelimesi “dip, alt” gibi anlamlara gelmektedir). Bu arada “fill” seçeneğinin değerinin de, bir önceki örneğin aksine, “X” olduğuna dikkat edin. Çünkü bu defa kaydırma çubuğumuzun x düzlemi üzerinde (yani soldan sağa doğru) boylu boyunca uzanması gerekiyor... Devam ediyoruz:
metin = Text(wrap=NONE, xscrollcommand=kaydirma.set)
metin.pack()
Şimdi de metin kutumuzu tanımladık. Buradaki parametrelere dikkat edin. Öncelikle metin kutumuza “wrap” adlı bir seçenek tanımlıyoruz. Bu “wrap” seçeneği metin kutusuna yazılan yazıların, ekranın sağ sınırına ulaşınca bir satır kaydırılıp kaydırılmayacağını belirliyor. Varsayılan olarak, yazılan metin ekranın sağ sınırına dayandığında otomatik olarak alt satıra geçecektir. Ama eğer biz bu “wrap” seçeneğine “NONE” değerini verirsek, metin sınırı geçip sağa doğru uzamaya devam edecektir. İşte aynı parantez içinde belirttiğimiz “xscrollcommand=kaydirma.set” seçeneği sayesinde sağa doğru uzayan bu metni kaydırabileceğiz. Burada, yukarıdaki örnekten farklı olarak “xscrollcommand” ifadesini kullandığımıza dikkat edin. Bir önceki örnekte “yscrollcommand” ifadesini kullanmıştık. Bu farkın nedeni, bir önceki örnekte “y” düzlemi üzerinde çalışırken, şimdiki örnekte “x” düzlemi üzerinde çalışıyor olmamız...
Artık son darbeyi vurabiliriz:
kaydirma.config(command=metin.xview)
mainloop()
Gördüğünüz gibi, burada da bir önceki örnekten farklı olarak “xview” ifadesini kullandık. Bir önceki örnekte “yview” ifadesini kullanmıştık. Bu farkın nedenini söylemeye gerek yok...
Gelin isterseniz bu parçalı örneği bir araya getirelim:
#!/usr/bin/env python
#-*-coding:utf-8-*-
from Tkinter import *
pencere = Tk()
kaydirma = Scrollbar(pencere, orient=HORIZONTAL)
kaydirma.pack(side=BOTTOM,fill=X)
metin = Text(wrap=NONE, xscrollcommand=kaydirma.set)
metin.pack()
kaydirma.config(command=metin.xview)
mainloop()