3. Geometri Yöneticileri¶
Şimdiye kadar yaptığımız örneklerden de gördüğünüz gibi, bir pencere aracını kullanıcılara gösterebilmemiz için bu aracı tanımlamak yeterli olmuyor. Aracı tanımlamanın yanısıra özel bir metodu da kullanmamız gerekiyor. Şu ana dek Tkinter ile hazırladığımız örneklerde pencere araçlarını kullanıcıya gösterebilmek için “.pack()” adlı özel bir metottan yararlandık. Bu metodun kullanımına şöyle bir örnek verebiliriz:
#!/usr/bin/env python
#-*-coding:utf-8-*-
from Tkinter import *
pencere = Tk()
pencere.geometry("200x100+50+100")
dolar = Label(text="Dolar",
fg = "white",
bg = "red",
font="Verdana 13 bold")
dolar.pack()
avro = Label(text="Avro",
fg = "white",
bg = "blue",
font="Verdana 13 bold")
avro.pack()
lira = Label(text="Lira",
fg = "white",
bg = "green",
font="Verdana 13 bold")
lira.pack()
mainloop()
Yukarıdaki pencere araçlarını gösterebilmek için kullandığımız “.pack()” adlı metoda Tkinter’de “geometri yöneticisi” (geometry manager) adı veriliyor. Anladığınız gibi, geometri yöneticilerinin temel işlevi Tkinter ile oluşturulan pencere araçlarını (yani “widget”leri) pencere üzerinde görünür hale getirmektir. Tkinter’de esasen üç farklı geometri yöneticisi bulunur. Bu geometri yöneticilerini şöyle sıralayabiliriz:
- pack()
- grid()
- place()
Geometri Yöneticileri bir pencere aracının konumunu belirler. 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.
Bu geometri yöneticileri içinde en kolay olanı pack() adlı yöneticidir. Zaten bu sebeple şimdiye kadar gördüğümüz örneklerde de hep bu pack() metodunu kullandık. Ancak hangi geometri yöneticisini kullanırsak kullanalım, öteki yöneticilerin nasıl kullanıldığını da öğrenmemiz gerekir. Çünkü bu geometri yöneticilerinin her birinin iyi olduğu bir alan vardır. Şimdi isterseniz bu geometri yöneticilerini tek tek inceleyelim...
3.1. pack() Geometri Yöneticisi¶
Bir önceki bölümde de söylediğimiz gibi, pack() geometri yöneticisi Tkinter’deki geometri yöneticileri içinde en kolay olanıdır. Bu geometri yöneticisinin kullanımıyla ilgili basit bir örneği önceki bölümde vermiştik. İsterseniz bu örneği tekrar önümüze alalım:
#!/usr/bin/env python
#-*-coding:utf-8-*-
from Tkinter import *
pencere = Tk()
pencere.geometry("200x100+50+100")
dolar = Label(text="Dolar",
fg = "white",
bg = "red",
font="Verdana 13 bold")
dolar.pack()
avro = Label(text="Avro",
fg = "white",
bg = "blue",
font="Verdana 13 bold")
avro.pack()
lira = Label(text="Lira",
fg = "white",
bg = "green",
font="Verdana 13 bold")
lira.pack()
mainloop()
pack() metodunu parametresiz olarak kullandığımızda öğelerin alt alta sıralandığına dikkat edin. Ancak gördüğünüz gibi, pack() metodunu bu şekilde kullandığımızda etiketler pencereye orantısız olarak dağılıyor. Yani görünüş biraz özensiz duruyor. Ama eğer biz istersek bu durumu bir nebze olsun düzeltebiliriz. Bunun için ihtiyacımız olan şey, pack() geometri yöneticisinin “expand” adlı seçeneğidir...
expand seçeneği
expand seçeneği, pencere araçlarının pencere üzerinde daha orantılı bir şekilde dağılmasını sağlar. Bu expand seçeneği “YES” ve “NO” olmak üzere iki farklı değer alır. Varsayılan değer “NO”dur... Bunu yukarıdaki örnek üzerinde görelim:
#!/usr/bin/env python
#-*-coding:utf-8-*-
from Tkinter import *
pencere = Tk()
pencere.geometry("200x100+50+100")
dolar = Label(text="Dolar",
fg = "white",
bg = "red",
font="Verdana 13 bold")
dolar.pack(expand=YES)
avro = Label(text="Avro",
fg = "white",
bg = "blue",
font="Verdana 13 bold")
avro.pack(expand=YES)
lira = Label(text="Lira",
fg = "white",
bg = "green",
font="Verdana 13 bold")
lira.pack(expand=YES)
mainloop()
“expand” kelimesi İngilizce’de “genişlet, yay” gibi anlamlara gelir. Yukarıdaki örnekte gördüğünüz gibi, pack() metoduna parametre olarak “expand = YES” seçeneğini vermek yoluyla öğelerin pencere üzerine “dağılmasını” veya “yayılmasını” sağlıyoruz. Eğer “expand = NO” gibi bir biçim kullanırsak, öğeler pencere üzerine yayılmayacak, yani sanki bu seçeneği hiç kullanmamışız gibi davranılacaktır...
Gördüğünüz gibi, öğeler yukarıdaki şekilde birbirinden ayrı duruyor. Biz bu öğelerin birbirine değmesini de isteyebiliriz. Yani tercihimiz, tıpkı bazı ülkelerin bayraklarında olduğu gibi, bu üç rengin şeritler halinde birbirine değecek şekilde uzanmasını sağlamak olabilir... Bu iş için kullanabileceğimiz ayrı bir seçenek var. Bu seçeneğin adı: fill.
fill seçeneği
Bu “fill” kelimesi İngilizce’de “doldurmak” anlamına gelir. Bu seçenek yardımıyla, araçlarımızın pencereyi doldurmasını sağlayacağız. “fill” seçeneği üç farklı değer alabilir: “X”, “Y” ve “BOTH”.
- “X” seçeneği, pencere aracımızın, içinde bulunduğu pencereyi x düzlemi boyunca doldurmasını sağlar (yani soldan sağa doğru)
- “Y” seçeneği, pencere aracımızın, içinde bulunduğu pencereyi y düzlemi boyunca doldurmasını sağlar (yani yukarıdan aşağıya doğru)
- “BOTH” seçeneği, pencere aracımızın, içinde bulunduğu pencereyi x ve y düzlemi boyunca doldurmasını sağlar (“both” kelimesi İngilizce’de “her ikisi de” anlamına gelir)
Şimdi bu seçenekleri örnekler üzerinde görerek kafamızda somutlaştıralım:
#!/usr/bin/env python
#-*-coding:utf-8-*-
from Tkinter import *
pencere = Tk()
pencere.geometry("200x100+50+100")
dolar = Label(text="Dolar",
fg = "white",
bg = "red",
font="Verdana 13 bold")
dolar.pack(expand=YES, fill = X)
avro = Label(text="Avro",
fg = "white",
bg = "blue",
font="Verdana 13 bold")
avro.pack(expand=YES, fill = Y)
lira = Label(text="Lira",
fg = "white",
bg = "green",
font="Verdana 13 bold")
lira.pack(expand=YES, fill = BOTH)
mainloop()
Burada her bir öğede ayrı bir değer kullandık. Ama eğer siz isterseniz her üçü için tek bir değer kullanarak, bu değerlerin tam olarak ne yaptığını daha net görmeyi tercih edebilirsiniz...
side seçeneği
side seçeneğini daha önce de kullanmıştık. Bu seçenek bir pencere aracını istediğimiz bir yöne yaslamamızı sağlıyor... Bu seçenek dört farklı değer alır: TOP, BOTTOM, LEFT ve RIGHT
- TOP: pencere aracını üste yaslar.
- BOTTOM: pencere aracını dibe yaslar.
- LEFT: pencere aracını sola yaslar.
- RIGHT: pencere aracını sağa yaslar.
Ancak bu dört değer içinde en sık kullanılanlar TOP ve LEFT’tir. Eğer pencere araçlarını yan yana sıralamak istersek kısaca “LEFT” değerini kullanabiliriz. Eğer pencere araçlarını üst üste sıralamak istersek de “TOP” değerini kullanabiliriz. Şu iki örneği dikkatlice inceleyin:
LEFT ile Kullanım:
#!/usr/bin/env python
#-*-coding:utf-8-*-
from Tkinter import *
pencere = Tk()
dolar = Label(text="Dolar",
fg = "white",
bg = "red",
font="Verdana 13 bold")
dolar.pack(side=LEFT)
avro = Label(text="Avro",
fg = "white",
bg = "blue",
font="Verdana 13 bold")
avro.pack(side=LEFT)
lira = Label(text="Lira",
fg = "white",
bg = "green",
font="Verdana 13 bold")
lira.pack(side=LEFT)
mainloop()
TOP ile Kullanım:
#!/usr/bin/env python
#-*-coding:utf-8-*-
from Tkinter import *
pencere = Tk()
dolar = Label(text="Dolar",
fg = "white",
bg = "red",
font="Verdana 13 bold")
dolar.pack(side=TOP)
avro = Label(text="Avro",
fg = "white",
bg = "blue",
font="Verdana 13 bold")
avro.pack(side=TOP)
lira = Label(text="Lira",
fg = "white",
bg = "green",
font="Verdana 13 bold")
lira.pack(side=TOP)
mainloop()
Ayrıca istersek birkaç seçeneği bir arada kullanarak aşağıdaki şekilde bir şey de yapabiliriz:
#!/usr/bin/env python
#-*-coding:utf-8-*-
from Tkinter import *
pencere = Tk()
dolar = Label(text="Dolar",
fg = "white",
bg = "red",
font="Verdana 13 bold")
dolar.pack(side=TOP, expand=YES,fill=BOTH)
avro = Label(text="Avro",
fg = "white",
bg = "blue",
font="Verdana 13 bold")
avro.pack(side=TOP,expand=YES, fill=BOTH)
lira = Label(text="Lira",
fg = "white",
bg = "green",
font="Verdana 13 bold")
lira.pack(side=TOP,expand=YES, fill=BOTH)
mainloop()
Bu pencereyi elle sağa-sola veya yukarı-aşağı doğru boyutlandırın. Gördüğünüz gibi, pencereyi ne şekilde boyutlandırırsanız boyutlandırın, etiket öğeleri pencereyi doldurmaya devam edecektir...
Elbette pack() geometri yöneticisi yalnızca etiketlerle birlikte kullanılmıyor. Öğrendiğimiz öteki pencere araçlarını da kullanarak, örneğin, şöyle bir şey yapabiliriz:
#!/usr/bin/env python
#-*- coding:utf-8-*-
from Tkinter import *
pencere = Tk()
uyari = Label(pencere,text="Programdan çıkmak istediğinize emin misiniz?")
uyari.pack()
evet = Button(text="Evet",command=pencere.quit)
evet.pack()
hayir = Button(text="Hayır")
hayir.pack()
mainloop()
Burada pack() metotları içinde değişik seçeneklere farklı değerler uygulayarak istediğinize yakın bir görüntü elde edebilirsiniz. Ancak mesela aşağıdaki gibi bir görüntü elde etmek için biraz uğraşmak gerekiyor:

Yukarıdaki gibi bir görüntü elde edebilmek için daha önce gördüğümüz Frame() adlı pencere aracından yararlanmanız gerekir. Frame() aracının nasıl kullanıldığını hatırlıyorsunuz:
#!/usr/bin/env python
#-*- coding:utf-8-*-
from Tkinter import *
pencere = Tk()
yeni = Frame()
yeni.pack(side=BOTTOM)
uyari = Label(pencere,text="Programdan çıkmak istediğinize emin misiniz?")
uyari.pack()
evet = Button(yeni,text="Evet",command=pencere.quit)
evet.pack(side=LEFT)
hayir = Button(yeni,text="Hayır")
hayir.pack()
mainloop()
Burada dikkatimizi çekmesi gereken bazı çok önemli yenilikler var. Mesela yukarıda geçen şu satıra bakın:
uyari = Label(pencere,text="Programdan çıkmak istediğinize emin misiniz?")
Kalın harflerle gösterdiğimiz ifade bizim için bir yenilik sayılır. Daha önceden yazdığımız pencere araçlarında, bu “pencere” ifadesini kullanmamıza gerek yoktu. Çünkü yazdığımız programlarda hep sadece tek bir “taşıyıcı pencere aracı” (container widget) yer alıyordu. Bu “taşıyıcı pencere aracı” ifadesi de ne oluyor, diye sorarsanız hemen açıklayalım: Görevi başka pencere araçlarını taşımak olan pencere araçlarına Tkinter’de “taşıyıcı pencere aracı” (container widget) adı veriliyor. Mesela yazdığımız bütün programlarda “pencere = Tk” ifadesi ile oluşturduğumuz ana penceremiz esasında bir taşıyıcı pencere aracıdır. Yani bu pencerenin görevi pencere araçlarını tutmaktır. Aynı şekilde “Frame()” de bir taşıyıcı pencere aracıdır. Bu pencere aracı da, tıpkı ana penceremiz gibi, başka pencere araçlarını üzerinde taşıyabilir. Mesela yukarıdaki örnekte Frame() pencere aracı bu görevde kullanılıyor. Nasıl “uyarı” adlı etiketi “pencere” adlı taşıyıcının üstüne yerleştirmişsek, “evet” ve “hayır” adlı pencere araçlarını da “yeni” adlı taşıyıcının üzerine yerleştiriyoruz. Bu yerleştirme işlemini, yukarıda gördüğünüz gibi, pencere araçlarının ilk argümanı olarak, herhangi bir taşıyıcı adı belirtmek suretiyle gerçekleştiriyoruz. Mesela “evet” adlı pencere aracını “yeni” adlı taşıyıcı üzerine yerleştirmişiz. Bunu “Button(yeni, text=”Evet”.....”) komutundaki kalın harflerle gösterilen ifadeden anlıyoruz... Aynı şekilde “uyarı” adlı pencere aracını “pencere” adlı taşıyıcının üzerine yerleştirdiğimizi de “Label(pencere,text=”Pr...”) komutundaki kalın harflerle gösterilen ifadeden anlıyoruz...
Peki Frame() aracını (ve pack yöneticisini) kullanarak başka neler yapabiliriz? Hemen bir örnek daha verelim:
#!/usr/bin/env python
#-*-coding:utf-8-*-
from Tkinter import *
pencere = Tk()
etiket = Label(text="Aşağıdaki kutucuğa e.posta adresinizi yazınız!")
etiket.pack()
giris = Entry()
giris.pack()
cerceve = Frame(height=2, bd=1, relief=SUNKEN)
cerceve.pack(fill=X, pady=5, padx=5)
dugme = Button(text="Gönder", command=pencere.destroy)
dugme.pack()
mainloop()
Burada birkaç yeni özellik görüyoruz. Daha önce görmediğimiz özellikler, “bd” ve “relief” seçenekleri... “bd” İngilizce’de “kenar, kenarlık, sınır” anlamına gelen “border” kelimesinin kısaltması... Bu seçenek yardımıyla Frame() aracının kenarlık ölçülerini belirliyoruz. Varsayılan olarak Frame() aracının kenarlık boyutu 0 (sıfır)’dır. Biz bunu yukarıda 1 olarak değiştirdik. Aynı satırda gördüğümüz “height” seçeneğini daha önce pencere boyutu ve entry konularını işlerken de görmüştük. Oradan hatırladığımıza göre, bu seçenek bir pencere aracının “yüksekliğini” ayarlamamızı sağlıyordu... Yukarıdaki örnekte de Frame() pencere aracının yüksekliğini “2” olarak ayarladık. “relief” seçeneği ise İngilizce bir kelime olarak Türkçe’de “kabartma (rölyef)” anlamına geliyor. Dolayısıyla bu seçenek yardımıyla pencere aracının “kabartma” tipini belirliyoruz. Burada altı farklı stil uygulayabiliriz:
- SOLID
- FLAT
- RIDGE
- SUNKEN
- GROOVE
- RAISED
Bu stillerin nasıl bir görüntü ortaya çıkardığını daha net görebilmek için “height” ve “bd” seçeneklerini daha yüksek değerlere ayarlamayı tercih edebilirsiniz.
Yukarıdaki örneğin sınıflı yapı içinde nasıl görüneceğine bakalım bir de...
#!/usr/bin/env python
#-*-coding:utf-8-*-
from Tkinter import *
class Uygulama(object):
def __init__(self):
self.guiPenAr()
def guiPenAr(self):
self.etiket = Label(text="Aşağıdaki kutucuğa e.posta adresinizi yazınız!")
self.etiket.pack()
self.giris = Entry()
self.giris.pack()
self.cerceve = Frame()
self.cerceve.pack(side=BOTTOM,
padx=5,
pady=5)
self.dugme = Button(self.cerceve,
text="Gönder",
width=5,
command=pencere.destroy)
self.dugme.pack(side=LEFT,padx=5)
self.dugme2 = Button(self.cerceve,
text="İptal",
width=5)
self.dugme2.pack()
pencere = Tk()
uyg = Uygulama()
mainloop()
Frame() aracını kullanarak mesela şöyle bir şey de yapabiliriz:
#!/usr/bin/env python
#-*-coding:utf-8-*-
from Tkinter import *
pencere = Tk()
etiket = Label(text="Aşağıdaki kutucuğa e.posta adresinizi yazınız!")
etiket.pack()
giris = Entry()
giris.pack()
cerceve = Frame()
cerceve.pack(side=BOTTOM,
padx=5,
pady=5)
dugme = Button(cerceve,
text="Gönder",
width=5,
command=pencere.destroy)
dugme.pack(side=LEFT,padx=5)
dugme2 = Button(cerceve,
text="İptal",
width=5)
dugme2.pack()
mainloop()
Burada pencere aracı seçeneklerini nasıl kullandığımıza dikkat edin.
İsterseniz bu örneği de sınıflı olarak ifade edelim:
#!/usr/bin/env python
#-*-coding:utf-8-*-
from Tkinter import *
class Uygulama(object):
def __init__(self):
self.guiPenAr()
def guiPenAr(self):
self.etiket = Label(text="Aşağıdaki kutucuğa e.posta adresinizi yazınız!")
self.etiket.pack()
self.giris = Entry()
self.giris.pack()
self.cerceve = Frame()
self.cerceve.pack(side=BOTTOM,
padx=5,
pady=5)
self.dugme = Button(self.cerceve,
text="Gönder",
width=5,
command=pencere.destroy)
self.dugme.pack(side=LEFT,padx=5)
self.dugme2 = Button(self.cerceve,
text="İptal",
width=5)
self.dugme2.pack()
pencere = Tk()
uyg = Uygulama()
mainloop()
pack() metodunu kullanarak çok karmaşık arayüz görüntüleri elde edebiliriz. Aslında bu metodu kullanarak yapamayacağımız şey yok gibidir. Ama bazı şeyleri bu metotla yapmaya kalkışmak bir süre sonra işkenceye dönüşebilir. O yüzden yeri geldiğinde pack() yerine başka metotları kullanmayı da bilmeliyiz... Mesela bazı işler için grid() metodu daha uygun olabilir... grid() metodunu anlatmaya geçmeden önce isterseniz pack() metodunu nerelerde kullanabileceğimizi şöyle bir sıralayalım:
- Pencere araçlarını alt alta dizmek istediğimizde,
- Pencere araçlarını yan yana dizmek istediğimizde,
- Pencere araçlarını alt alta veya yan yana dizip, bunların pencereyi (x veya y düzleminde ya da her ikisinde birden) tamamen kaplamasını istediğimizde.
Bu metodu nerelerde kullanmamızın uygun olacağını gördüğümüze göre artık başka bir geometri yöneticisini anlatmaya başlayabiliriz.
3.2. grid() Geometri Yöneticisi¶
Bu geometri yöneticisi, pencere araçlarının “ızgara” biçiminde sıralanacağı arayüzler için uygundur. Bununla hemen basit bir örnek yapalım:
# -*- coding: utf-8 -*-
from Tkinter import *
dugme1 = Button(text="Ürünler")
dugme1.grid()
dugme2 = Button(text="Hizmetler")
dugme2.grid()
dugme3 = Button(text="Ulaşım")
dugme3.grid()
dugme4 = Button(text="Hakkında")
dugme4.grid()
mainloop()
grid() adlı geometri yöneticisi basitçe bu şekilde kullanılıyor. Ama tabii ki bu haliyle pek cazip görünmüyor. Buna istediğimiz şekli verebilmek için yine birtakım seçeneklerden yararlanmamız gerekecek:
row seçeneği
Bu geometri yöneticisinin en önemli iki seçeneğinden birincisi bu “row” seçeneğidir. Bu kelime İngilizce’de “satır” anlamına gelir. Bu seçenek yardımıyla, pencere aracının hangi satırda yer alacağını belirleyeceğiz. Bununla herhangi bir örnek yapmadan önce, isterseniz grid() geometri yöneticisinin öteki seçeneğinden de bahsedelim. Çünkü bu seçenek hep “row” seçeneğiyle birlikte kullanılır.
column seçeneği
“column” kelimesi İngilizce’de “sütun” anlamına gelir. Dolayısıyla bu seçenek yardımıyla pencere aracımızın pencere üzerinde hangi sütunda yer alacağını belirleyeceğiz. Artık bu iki seçeneği kullanarak bir örnek verebiliriz. Aşağıdaki örneği dikkatle inceleyin:
# -*- coding: utf-8 -*-
from Tkinter import *
dolar = Label(text="Dolar")
dolar.grid(row=0,column=0)
avro = Label(text="Avro")
avro.grid(row=1,column=0)
lira = Label(text="Lira")
lira.grid(row=2,column=0)
dolar_g = Entry()
dolar_g.grid(row=0,column=1)
avro_g = Entry()
avro_g.grid(row=1,column=1)
lira_g = Entry()
lira_g.grid(row=2,column=1)
Gördüğünüz gibi bu grid() metodu yardımıyla pack() metoduna kıyasla daha “ince” ayarlamalar yapabiliyoruz. “grid()” metodu bize, pencere aracımızın koordinatlarını daha hassas bir şekilde belirtme imkanı sunuyor. Şimdi isterseniz ilk verdiğimiz, “cazip görünmeyen” örneği yeniden ele alalım. Örneğimiz şuydu:
# -*- coding: utf-8 -*-
from Tkinter import *
dugme1 = Button(text="Ürünler")
dugme1.grid()
dugme2 = Button(text="Hizmetler")
dugme2.grid()
dugme3 = Button(text="Ulaşım")
dugme3.grid()
dugme4 = Button(text="Hakkında")
dugme4.grid()
mainloop()
Şimdi yapacağımız şey, pencere üzerinde dağınık bir şekilde duran bu araçların her biri için uygun bir satır-sütun belirlemek. Hemen bakalım:
# -*- coding: utf-8 -*-
from Tkinter import *
dugme1 = Button(text="Ürünler")
dugme1.grid(row=0, column=0)
dugme2 = Button(text="Hizmetler")
dugme2.grid(row=0, column=1)
dugme3 = Button(text="Ulaşım")
dugme3.grid(row=1, column=0)
dugme4 = Button(text="Hakkında")
dugme4.grid(row=1,column=1)
mainloop()
İsterseniz daha önceden gördüğümüz “fg”, “bg” ve “font” gibi seçenekler yardımıyla bu düğmelerin ve üzerindeki yazıların renklerini gönlünüze göre değiştirebilirsiniz de...
Dediğimiz gibi, grid() yöneticisinin en uygun kullanım alanı “ızgara” biçimli arayüzlerdir. Mesela hesap makineleri... Şu örneğe bir bakalım:
#!/usr/bin/env python
#-*-coding:utf-8-*-
from Tkinter import *
pencere = Tk()
#bir hesap makinesinde pencerenin boyutlandırılabilir olması anlamsız olacaktır.
#O yüzden pencereleri boyutlandırılamaz hale getiriyoruz.
pencere.resizable(width=FALSE,height=FALSE)
#hesap makinemizin tuş takımında yer alacak simgeleri ve sayıları oluşturuyoruz.
liste = [\
"9", "8", "7",
"6", "5", "4",
"3", "2", "1",
"0", "+", "-",
"/", "*", "=",
"C"]
#grid() yöneticisinin row (sıra) ve column (sütun) seçenekleri için birer başlangıç
#değeri belirliyoruz.
sira = 1
sutun = 0
#tuş takımındaki bütün pencere araçlarını tek bir for döngüsü ile oluşturuyoruz.
for i in liste:
Button(text=i,width=4,relief=GROOVE).grid(row=sira,column=sutun)
sutun += 1 #column seçeneğinin değeri her defasında bir sayı artıyor.
if sutun > 2: #sutun'un yani "column'un" değeri 2'yi geçtiğinde,
sutun = 0 #column'un değerini sıfırlıyoruz. Böylece tuşlar
#alt alta dizilebiliyor.
sira += 1 #row'un (sıra) değeri de her defasında bir sayı artıyor.
mainloop()
Gördüğünüz gibi, yukarıda bir hesap makinesinde olması gereken temel tuşları, basit bir for döngüsü yardımıyla bir çırpıda oluşturduk. Yukarıda kodlar içinde verdiğim yorumları dikkatlice incelemenizi öneririm. Aşağıda hesap makinemizin bitmiş halini bulabilirsiniz:
#!/usr/bin/env python
#-*-coding:utf-8-*-
from __future__ import division
from Tkinter import *
depo = ""
pencere = Tk()
pencere.resizable(width=FALSE,height=FALSE)
ekran = Entry(width=20)
ekran.grid(row=0, column=0, columnspan=3,ipady=4)
def hesapla(tus):
global depo
if tus in "0123456789":
ekran.insert(END,tus)
depo = depo + tus
if tus in "+-/*":
depo = depo + tus
ekran.delete(0,END)
if tus == "=":
ekran.delete(0,END)
#Normalde tehlikeli bir fonksiyon olan eval()'i nasıl
#kullandığımıza dikkat edin...
hesap = eval(depo,{"__builtins__":None},{})
depo = str(hesap)
ekran.insert(END,depo)
if tus == "C":
ekran.delete(0,END)
depo = ""
liste = [\
"9", "8", "7",
"6", "5", "4",
"3", "2", "1",
"0", "+", "-",
"/", "*", "=",
"C"]
sira = 1
sutun = 0
for i in liste:
komut = lambda x=i: hesapla(x)
Button(text=i,
width=5,
relief=GROOVE,
command=komut).grid(row=sira,
column=sutun)
sutun += 1
if sutun > 2:
sutun = 0
sira += 1
mainloop()
Bu hesap makinesinde aklınıza takılan bir konu olursa bana nasıl ulaşacağınızı biliyorsunuz... Bu arada isterseniz hesap makinemizi bir de sınıflı yapı içinde görelim:
#!/usr/bin/env python
#-*-coding:utf-8-*-
from __future__ import division
from Tkinter import *
class Uygulama(object):
def __init__(self):
self.guiPenAr()
self.gV()
def gV(self):
self.depo = ""
def guiPenAr(self):
self.ekran = Entry(width=20)
self.ekran.grid(row=0, column=0, columnspan=3,ipady=4)
self.liste = [\
"9", "8", "7",
"6", "5", "4",
"3", "2", "1",
"0", "+", "-",
"/", "*", "=",
"C"]
self.sira = 1
self.sutun = 0
for i in self.liste:
self.komut = lambda x=i: self.hesapla(x)
Button(text=i,
width=5,
relief=GROOVE,
command=self.komut).grid(row=self.sira,
column=self.sutun)
self.sutun += 1
if self.sutun > 2:
self.sutun = 0
self.sira += 1
def hesapla(self, tus):
self.tus = tus
if self.tus in "0123456789":
self.ekran.insert(END,self.tus)
self.depo = self.depo + self.tus
if self.tus in "+-/*":
self.depo = self.depo + self.tus
self.ekran.delete(0,END)
if self.tus == "=":
self.ekran.delete(0,END)
self.hesap = eval(self.depo,{"__builtins__":None},{})
self.depo = str(self.hesap)
self.ekran.insert(END,self.depo)
if self.tus == "C":
self.ekran.delete(0,END)
self.depo = ""
pencere = Tk()
pencere.resizable(width=FALSE,height=FALSE)
uyg = Uygulama()
mainloop()
Dikkat ederseniz, bir önceki bölümde pack() yöneticisini incelerken öğrendiğimiz “GROOVE”, “SUNKEN”, vb. stilleri grid() geometri yöneticisiyle birlikte de kullanabiliyoruz.
Böylelikle bir geometri yöneticisini daha incelemiş olduk. Sıra geldi sonuncu geometri yöneticimize...
3.3. place() Geometri Yöneticisi¶
Tahminimce bu geometri yöneticisi Tkinter’deki üç yönetici içinden en çok beğeneceğiniz yönetici olmaya adaydır... Bütün geometri yöneticileri içinde, pencere araçlarını en hassas şekilde yerleştirmemizi sağlayan yönetici place() adlı geometri yöneticisidir...
place() geometri yöneticisi ile çalışırken bize temel olarak iki seçenek yardımcı olacak: “relx” ve “rely”. Tahmin edebileceğiniz gibi, “relx” x düzlemi üzerindeki işlemler için, “rely” ise “y” düzlemi üzerindeki işlemler için kullanılacak. Hemen bir örnek görelim:
#!/usr/bin/env python
#-*- coding:utf-8-*-
from Tkinter import *
pencere = Tk()
giris1 = Entry()
giris1.place(relx=0.0, rely=0.0,relheight=0.15)
dugme1 = Button(text="Düğme1")
dugme1.place(relx=0.7, rely=0.0,relheight=0.16)
dugme2 = Button(text="Düğme2")
dugme2.place(relx=0.0,rely=0.2,relwidth=1)
giris2 = Entry()
giris2.place(relx=0.0,rely=0.35,relheight=0.5,relwidth=1)
mainloop()
Bu örnekte “relx” ve “rely” seçeneklerinin yanısıra, “relheight” ve “relwidth” seçeneklerini de kullandık. Rahatlıkla anlayabileceğiniz gibi, bu place() yöneticisi yardımıyla pencerelerimizi istediğimiz şekilde düzenleyebiliyoruz. Ama tabii ki, gördüğünüz gibi, koordinatları tam olarak vermeyi gerektirdiği için bu yöneticiyle çalışmak biraz emek istiyor. Bu yüzden bazı işler için bu yöneticiyi kullanmak pek pratik olmayabilir. Böyle durumlarda öteki yöneticilerin neler yapabileceğini de göz önünde bulundurmakta fayda var... Bir sonraki konumuz olan “checkbutton pencere aracı”nda place() adlı geometri yöneticisinden bahsetmeye devam edeceğiz.