14 Ağustos 2008 Perşembe

PyGtk ile HelloWorld

İnternette Gtk ile ilgili Türkçe bir döküman aradığınızda bilgiden çok küfür var nedense. Aman abi sen ne yapıyorsun ,acayip zor ,imkansız sadece über-geek'ler gtk kullanarak programlama yapabilir. Gtk ile programlama yapanın geyşası olurum gibi yorumlar yükseliyor. Bende bu sebepten başlangıçta kendimi qt yolunda zorlamıştım fakat yapamadım. Gtk fetişim xfce ile birlikte nirvanasına ulaştı genç zihnime bir karabasan gibi bulaştı. fazla lafı uzatmadan gtk nedir ne değildir diye kimseyi yormadan Türk internet medyasını büyük bir açlıktan kurtarayım dedim.
PyGtk hello world şeysi.
İlk önce glade denen tasarım aracımızla en basit manada bir arayüz tasarlayalım. Yorumları tahmin edebiliyorum neden arayüzü glade ile yapıyorsun delikanlı gibi kodlayarak yapsana diye.. css olmadan html kodlamak neyse glade olmadan gtk kodlamak (diğer gui api'lerini bilmediğim için birşey söyleyemiyorum) odur. Glade ile arayüzünüzü tarif eden bir xml dosyası oluşturursunuz. Sonra bunu programınızın içinde ayrıştırır ("parse" demeyeceğim) kullanırsınız. Kodunuz ayrı tasarımınız ayrı olur , 1000 satırlık değil 100 satırlık kodla güreş tutarsınız gözleriniz şeş beş bakmazsınız.

  • Yeni bir glade dosyası açın

  • bir adet window ekleyin

  • içine bir adet button nesnesi ekleyin, etiketine hello world gibi bişi yazın

  • pencerenin ismi w1, düğmenin ismi d1 olsun.


Sinyaller ve işleyiciler:
Sinyal'ler aslında hareketlerdir düğmeye basıldı, nesne yokedilmek istendi , sürükleyip bıraktılar beni vs gibi. İşleyici de bu aksiyon karşısında widget'in arkadaşlarına ne diye bağırdığı desek yeridir. Örneğin b1 tuşu tıklandığı zaman "bana tıkladılar imdat" diye bağırıyor , ve bunu dinlemekle görevli olan fonksiyon bu sesi duyunca yettim gayri değip çalışmaya başlıyor...

  • w1 widget'ının (Türkçesini bulursam yazıcam) sinyaller sekmesine girin GtkObject altındaki destroy sinyalinin yanına "w1_kapatilmak_istendi" yazın.

  • b1 widget'ının sinyaller sekmesine gidin clicked sinyalinin yanına işleyici olarak "d1_basıldı" yazın.

  • dosyayı hello.glade adıyla kaydedin.


Godlamaya başlayabiliyin aybalam:
En sevdiğiniz editörle yeni bir python dosyasına başlayın en sevdiğiniz 2 satırı bu dosyanın başına yazın.
#!/usr/bin/env python
# -*- coding: utf-8 -*-

ilk önce pygtk modülünü ve sys modülünü import eyleyin.
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import pygtk ,sys

sonra pygtk ya senin bana version 2.0'ın lazm değilsen işime yaramazsın diyeceğiz. pygtk.require('2.0') eğer exception kaldırırsa versionu 2.0 dan aşağı demektir o zaman program çalışmasın.
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import pygtk, sys

try:
pygtk.require('2.0')
except:
print "versiyon tutmadı..."
sys.exit(1)


Eğer pygtk 2.0 var ise geri kalan gerekli modülleri import edelim..
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import pygtk, sys
try:
pygtk.require('2.0')
except:
print "versiyon tutmadı..."
sys.exit(1)

import gtk , gtk.glade

Şimdi glade dosyamızı ayrıştıralım , içinden w1 ve b1 nesnemizi kullanmak üzere birer değişkene atayalım.
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import pygtk, sys

try:
pygtk.require('2.0')
except:
print "versiyon tutmadı..."
sys.exit(1)

import gtk , gtk.glade

window_tree = gtk.glade.XML('hello.glade')
window = self.wtree.get_widget('w1')
button = self.wtree.get_widget('b1')

Artık bu nesnelere ait işlemleri gerçekleştirebiliriz. ama önce programa hangi sinyali ne için kullanacağımızı belirtelim bunu yapmak için hangi işleyicinin hangi fonksiyonu tetikleyeceğini bir sözlük üzerinde topluyor sonra autoconnect ile bu işlemleri fonksiyonlara bağlıyoruz.
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import pygtk, sys
try:
pygtk.require('2.0')
except:
print "versiyon tutmadı..."
sys.exit(1) # [*1]

import gtk , gtk.glade

window_tree = gtk.glade.XML('hello.glade')
window = self.wtree.get_widget('w1')
button = self.wtree.get_widget('b1')
signals = {'w1_kapatilmak_istendi' : end_program,
'd1_basıldı' : end_program}
window_tree.signal_autoconnect(signals)


Gördüğünüz gibi tuşa basıldığı zaman ve pencere kapatılmak istendiği zaman end_program fonksiyonuna yönlendiriyoruz... peki bu end_program fonksiyonunu nasıl tanımlayacağız?
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import pygtk, sys
try:
pygtk.require('2.0')
except:
print "versiyon tutmadı..."
sys.exit(1) # [*1]

import gtk , gtk.glade

window_tree = gtk.glade.XML('hello.glade')
window = self.wtree.get_widget('w1')
button = self.wtree.get_widget('b1')
signals = {'w1_kapatilmak_istendi' : end_program,
'd1_basıldı' : end_program}

def end_program(self,widget,data=None):
print "Güle güle..."
gtk.main_quit()

# sinyalleri bağlamadan önce fonksiyonların
# tanıtılmış olması gerekiyor

window_tree.signal_autoconnect(signals)

Burada dikkat etmemiz gereken şey şu gtk nın sinyalleri tarafından çağırılan fonksiyonların zorunlu olarak alması gereken sırasıyla self, widget , data=None argümanları.. Aslında bunu ezberleyin çünkü hep bu şekilde kullanacaksınız.
Widget'larla işimiz bittiğine göre w1'e göster kendini emrini verelim. ve son olarak gtk ya ben işimi bitirdim bundan sonra kontrol sende demek için gtk.main() diyelim.
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import pygtk, sys
try:
pygtk.require('2.0')
except:
print "versiyon tutmadı..."
sys.exit(1) # [*1]

import gtk , gtk.glade

window_tree = gtk.glade.XML('hello.glade')
window = self.wtree.get_widget('w1')
button = self.wtree.get_widget('b1')
signals = {'w1_kapatilmak_istendi' : end_program,
'd1_basıldı' : end_program}

def end_program(self,widget,data=None):
print "Güle güle..."
gtk.main_quit()

window_tree.signal_autoconnect(signals)
gtk.main()
window.show()


işte sonuç...


Buradaki kodların boşluk karakterlerinde falan bozukluk olabilir siz en iyisi kodlara şuradan da bir bakın.


hello.py
hello.glade

4 yorum:

  1. Merhaba.

    pygtk.require('2.0') ifadesinin önüne print ifadesi karışmış. Diğer yazılardaki kodlara baktığımda kod girintilemesi yapmışsınız fakat bu yazıdaki kodlarda girintileme yapmamışsınız.

    YanıtlaSil
  2. @fatih:
    Uyarı için teşekkürler. Sanırım ilk yazılardan olmasından dolayı gözlerden kaçmış.

    @Mirat Can Bayrak:
    Sonumuz olacaksın yahu =)

    YanıtlaSil
  3. yav hocam şimdi sorum var ben bunu daha öncede okumuştum tamam bu şekilde oluyor fakat kafam şu mantık var hala :)
    mesela delphide butonu koyar butonun altına işlevini yazardık fakat glade de bi farklılık var gibi yada geç oldu ben kafamı veremiyorum..
    mantık nasıl olmalı, yani bi form tasarımına göre programı yazmak mı? yoksa programla birlikte formuda birlikte mi yazmalı yada programı yazıp formu ona göre mi ayarlamalı :| :D sapıttım azcık özür :D
    form tasarımım var programım var ve ben nasıl bunları birleştirecem diye düşünüyorum :D ben şu yazıyı bi daha okuyayım, biraz daha araştırayım bu mantık oturmaz yoksa :D kolay gelsin.. hep o windowsun suçu o dar kalıplara sürüklemiş bizi..

    YanıtlaSil
  4. Bu yorum yazar tarafından silindi.

    YanıtlaSil