28 Aralık 2009 Pazartesi

Diyalogların Kullanımı

  WxRuby'de uygulamamızı standart görüntülerle süsleyecek birçok öntanımlı diyalog kutusu bulunur. Bu yazıda kullanıcımızdan girdi alabileceğimiz üç diyalog kutusu göreceğiz.

  1. Mesaj diyaloğu
  2. Text girişi
  3. Listeden seçim
Bundan başka daha birçok standart diyalog bulunur. Örneğin , dosya seçici , renk seçici , progress diyalog , font seçici gibi.

Mesaj Bildirileri

Kullanıcıyla yapabileceğimiz en basit iletişim Wx::MessageDialog adındaki basit alarm kutusunu kullanmaktır. MessageDialog kullanarak üzerinde sadece bir mesaj ve OK butonu olan bir kutu veya Yes/No butonları ile cevap alabileceğimiz bir kutu yapabiliriz.

1     dlg = MessageDialog.new nil, "böyle iletişim kurması kolay mı ?", "MessageDialog", YES_NO | ICON_QUESTION 
2     result = dlg.show_modal
3     p result
4     dlg.destroy

bu kodun karşılığında  şöyle bir diyaloğumuz olur :



 MessageDialog nesnesinin tanıtım parametreleri şunlardır :

MessageDialog.new(Window parent,  String message, 
                  String caption = "Message box", 
                  Integer style = OK CANCEL, 
                  Point pos = DEFAULT_POSITION)

Burda parent dialogun çağrıldığı penceredir veya bir pencereye bağlı olmasını istemezsek nil değer gireriz. Arkasından mesajımızı string olarak gireriz. "caption" isimli string diyaloğumuzun titlebar'ında görünecek yazıdır, default değeri "Message box". "style" parametresi diyaloğumuzda bulunacak butonları ve ikonları tarif eden bir bitmask'dır. "pos" parametresi de diyaloğumuzun ekranda gösterileceği pozisyonu belirtir bir Wx::Point nesnesidir. "show_modal" ile diyaloğumuz modal olarak açılır yani bu diyalog açıldığında uygulamamızda olan pencerelerde işlem yapmamız diyaloğumuz kapatılana kadar engellenir. Tüm diyaloglarda bu metod ortakdır. "show_modal" metodunun geri dönen değeri diyaloğumuzun sonucunu ifade eden bir integer sayıdır. Bu diyaloğumuzda tıklanan butonun kodu geri döner. Bu "MessageDialog" nesnesi için şu sabitlerden biridir : Wx::ID_YES , Wx::ID_NO , Wx::ID_CANCEL , Wx::ID_OK.
Style bitleri ile diyaloğumuzda bulunacak butonlara karar veririz. Wx::OK , Wx::CANCEL , Wx::YES_NO . Ayrıca bu style bitleri ile diyaloğumuzda hangi ikonun görüneceğini seçeriz. Wx::ICON_ERROR , Wx:ICON_EXCLAMATION , Wx::ICON_INFORMATION , Wx::ICON_QUESTION .


Bir Satırlık Yazı Girdisi

Eğer kullanıcıdan bir tek satır bilgi almak istiyorsak , "TextEntryDialog" kullanırız. Bu nesne bir diyalog penceresi açar ve eğer kullanıcı OK butonunu tıklarsa girilen yazıyı geri döner.

17     dlgq = TextEntryDialog.new nil, "Sevdiğiniz Programlama Dili Nedir ?", "Bir Soru", "Ruby"
18     if dlgq.show_modal == ID_OK
19       response = dlgq.get_value
20       p response + " güzel bir seçim"
21     end
22     dlgq.destroy

 

Bu kodun karşılığı diyaloğumuz şuna benzer :



TextEntryDialog nesnesi üretirken girdiğimiz parametreler sırasıyla şunlar : her zaman olduğu gibi parent en başta. Arkasından diyaloğumuzun içinde yer alacak soru cümlemiz string olarak. Bundan sonra diyaloğumuzun etiketinde yer alacak string gelir. En son text girişinde yer alacak default yazı geliyor. Ayrıca default değeri Wx::OK | Wx::CANCEL olan bir style bilgisi vardır. İstersek sadece OK butonu bırakabiliriz. Aynı MessageDialog nesnesi gibi show_modal metodu da tıklanan düğmenin kodunu geri döner. "get_value" metodu textbox'ta yazılmış olan değeri geri döner. Burda sadece deneme için girilen değeri terminale geri yazıyoruz.



Aşağıdaki Listeden Seçiniz

Eğer kullanıcının her aklına geleni yazmasını değilde bizim istediğimiz yanıtlardan birini seçmesini istiyorsak , Wx::SingleChoiceDialog nesnesi kullanırız. Bu nesnenin basit kullanımı şöyledir :

24     dlgc = SingleChoiceDialog.new nil, "Kaç Yaşında Evlenmek Daha İyi ?", "Birini Seçin", ["15", "20", "25", "36", "44"]
25     if dlgc.show_modal == ID_OK
26       response = dlgc.get_string_selection
27       p response + " yaş çok erken olur !"
28     end
29     dlgc.destroy


Bu kodun sonucu şu şekil bir diyaloğumuz olur :



Bir öncekinden farklı olarak burda default text değeri yerine bir matris içinde seçenekleri gireriz. Bu diyalogdan dönen değeri iki değişik şekilde alabiliriz : "get_selection" metodu seçilen stringin indexini geri döner , "get_string_selection" ile seçilen stringin kendisini alırız.  
Tüm bu kodların hepsini ana penceresi olmayan bir uygulamaya dizdim :


1 #!/usr/bin/env ruby
 2 # dialoglar.rb kullaıcı ile diyalog pencereleri yardımıyla iletişim
 3 
 4 require 'rubygems'
 5 require 'wx'
 6 include Wx
 7 
 8 $KCODE = "utf8"               #Türkçe karakterler terminalde çıksın
 9 
10 class MyApp < App
11   def on_init
12 
13     dlg = MessageDialog.new nil, "böyle iletişim kurması kolay mı ?", "MessageDialog", YES_NO | ICON_QUESTION
14     result = dlg.show_modal
15     p result
16     dlg.destroy
17 
18     dlgq = TextEntryDialog.new nil, "Sevdiğiniz Programlama Dili Nedir ?", "Bir Soru", "Ruby"
19     if dlgq.show_modal == ID_OK
20       response = dlgq.get_value
21       p response + " güzel bir seçim"
22     end
23     dlgq.destroy
24 
25     dlgc = SingleChoiceDialog.new nil, "Kaç Yaşında Evlenmek Daha İyi ?", "Birini Seçin", ["15", "20", "25", "36", "44"]
26     if dlgc.show_modal == ID_OK
27       response = dlgc.get_string_selection
28       p response + " yaş çok erken olur !"
29     end
30     dlgc.destroy
31 
32   end
33 end
34 
35 if __FILE__ == $0
36   my_app = MyApp.new
37   my_app.main_loop
38 end
39 

Bu günlük bu kadar.

17 Aralık 2009 Perşembe

Frame'e Menubar, Toolbar veya Statusbar Eklemek

Bir uygulama penceresinin genelde 3 temel görsel vardır. En üstte bir menübar, onun altında bir toolbar ve pencerenin altında bir statusbar. Şekilde böyle bir pencere resmi görünüyor.



Aşağıdaki programı toolbar.rb adıyla kaydedin.

 1 #!/usr/bin/env ruby
2 # Toolbar.rb Frame'e Menu ve Toolbar Eklemek
3
4 require 'rubygems'
5 require 'wx'
6 include Wx
7
8 class ToolbarFrame < Frame
9 def initialize
10 super nil, -1, "Toolbar", :size=>Size.new(300, 200)
11 panel = Panel.new self
12 panel.set_background_colour WHITE
13 status_bar = create_status_bar #1 statusbar üretiliyor
14 tool_bar = create_tool_bar #2 toolbar üretiliyor
15 tool_bar.add_tool -1, "New", xpm_bitmap("new.xpm"), "Long help for 'New' " #3 toolbara buton ekleniyor
16 tool_bar.realize
17 menubar = MenuBar.new
18 menu1 = Menu.new
19 menubar.append menu1, "&File"
20 menu2 = Menu.new
21 menu2.append -1, "&Copy", "Copy in Statusbar"
22 menu2.append -1, "C&ut", "-"
23 menu2.append -1, "Paste", " "
24 menu2.append_separator
25 menu2.append -1, "&Options...", "Display Options"
26 menubar.append menu2, "&Edit"
27 set_menu_bar menubar
28 end
29
30 # bir Bitmap icon nesnesi döner
31 def xpm_bitmap(base_name)
32 # betiğin bulunduğu klasörde icons adında bir alt klasörde iconlar var
33 xpm_file = File.join( File.dirname(__FILE__), 'icons', base_name )
34 Wx::Bitmap.new(xpm_file, Wx::BITMAP_TYPE_XPM)
35 end
36
1 işaretli satır Wx::StatusBar nesnesinin bir oluşumunu üretiyoruz. Status bar frame gösterilmesiyle beraber en alta yerleşir ve orada yapışık olarak kalır. Status bar uygulama çalışması esnasında çeşitli bilgilendirmeler için kullanılır. Statusbar yazı boyutu ve şekli işletim sistemi tarafından belirlenir.

2 işaretli satırda Wx::ToolBar nesnesinin bir oluşumu üretiyoruz ve bu da pencerenin üst kısmına yayılır. Toolbar üzerinde çeşitli komutları yerine getirecek resimli butonlar olur.

3 işaretli satırda toolbar'a bir buton ekliyoruz. Bunu yaparken resim için bir bitmap nesnesi gerekiyor. Bunun için de xpm_bitmap adında bir metod yardımıyla betiğin bulunduğu klasöre eklediğimiz "icons" klasörü içinden bir resim dosyası çağırıyoruz. Bu klasörü WxRuby gem klasörü içindeki bigdemo örneğinin olduğu klasörde bulabilirsiniz. Mesela bende bu resimleri "/usr/lib/ruby/gems/1.8/gems/wxruby-2.0.0-x86-linux/samples/bigdemo/icons" klasöründe buldum. Daha sonra realize metodu ile toolbar'a butonlarının yerleştirmesini otomatik olarak yapmasını emrediyoruz.

Daha sonra bir MenuBar nesnesi üretiyoruz. MenuBar nesnesi pencerenin en üstüne yerleşir. Bu nesneye Menu nesneleri ekleyerek uygulamanın menüleri oluşturulur. Burda 2 adet Menu nesnesi üretiyoruz. Sonra bu menü nesnelerine alt menü komutları ekliyoruz. Hem menubar'a menu nesnesi eklerken hem de menu'ye altmenü eklerken append metodu kullanıyoruz. Menüye ulaşmak için kısayol tuşu olacak harfin önüne & işareti koymamız gerekiyor. Alt menüleri eklerken girilen 3. parametredeki string mouse menü üzerinde gezerken status barda görünür.





15 Aralık 2009 Salı

WxRuby uygulamanıza sağlam bir temel vermek

Bir WxRuby uygulamasının iki temel parçası vardır, uygulama nesnesi ve üst seviye pencere nesnesi (top level window). Uygulama nesnesi esas çevrim programını barındırır, bu yüzden uygulama nesnesi olmadan bir WxRuby uygulaması olamaz.
Üst seviye pencere ise kullanıcıya sunulacak en önemli kontrolleri ve verileri içerir. Örneğin bir kelime işlemci programında üst seviye pencere hem dökümanı gösterirken aynı zamanda dökümanla ilgili birçok veriyi de barındırır. Aynı şekilde bir web tarayıcının üst seviye penceresi hem sayfayı gösterir hem sayfa hakkında bilgiler barındırır. Aşağıdaki şekil bu iki temel nesnenin birbirleri ve uygulamanın geri kalanıyla bağlantılarını gösterir.

Bu diyagramda da göründüğü gibi uygulama nesnesi ana olay çevrimi ve üst seviye pencereyi içerir. Üst seviye pencere üzerindeki kontrolleri ve iliştirdiğiniz diğer veri nesnelerini içerir. Bu pencere ve içindeki kontroller kullanıcının hareketlerinden olayları tetikler.

Her WxRuby programı bir adet uygulama nesnesi bulundurmalıdır. Uygulama nesnesi Wx::App sınıfının bir oluşumu veya altsınıfıdır. Uygulama nesnesinin esas amacı ana olay çevrimini yönetmektir. Bu olay çevrimi pencere sisteminden gelen olay isteklerini işler ve ilgili olay işleyici rutinlere yönlendirir. Ayrıca bu uygulama nesnesi uygulama geneli nesneler de barındırabilir (veritabanı bağlantıları gibi).

Wx:App alt sınıfını üretmek

Bu altsınıfı üretmek kolay olduğundan ek bir özellik gerekmese bile bu altsınıfı üretmek yapısal olarak doğru olacaktır. Bu altsınıfı üretmek için dört adım yapılır :

  1. Altsınıf tanımlamasını yaparız.

  2. “on_init” metodunu bu tanımlama içine koyarız.

  3. Programımızın ana bölümünde bu sınıfın bir oluşumunu üretiriz.

  4. Bu oluşumun “main_loop” metodunu çağırırız ve kontrol WxRuby'ye geçer.

“on_init” metodu uygulama başlayınca ana çevrime girmeden önce çalışır. Bu metod parametre almaz ve bir bool değer döner. Eğer bu metod false dönerse uygulama hemen sona erer. Tipik olarak on_init metodu içinde enazından bir frame tanımlaması yapılır. Ayrıca bu frame'in show metoduda burda olur. Ayrıca bu frame'in uygulamanın üst seviye penceresi olduğunu da set_top_window ile tanıtabiliriz. Üst seviye pencere sahibi tanıtılmamış diyalog pencereleri için default “sahip” tir.

Wx::Frame nesnesi ile çalışmak

WxRuby'de frame kullanıcıların pencere diye isimlendirdiği GUI elemanıdır. WxRuby'de tüm pencerelerin üst sınıfı Wx::Frame dir. Frame altsınıfını üretirken initialize metodu içinde üst sınıf parametreleriyle çağırılır. Bu parametrele şöyledir :

Wx::Frame.new( parent , id , title , pos=DEFAULT_POSITION ,

size=DEFAULT_SIZE , style=DEFAULT_FRAME_STYLE , name=”frame”)

Bir çok kontrol de benzer parametreler alır.



Parametre

Açıklaması

parent

Frame'in içine yerleşeceği yer. Üst seviye pencereler için bu parametre nil değeri alır. Eğer frame bir pencere içine yerleşecekse parent o penceredir. Bu durumda frame parent'in içinde beraber büyüyecek ve hareket edecektir. Parent kapanırsa bu frame de kapanır.

id

Frame kontrolü id numarası. Buraya özel bir sayı girebilirsiniz ya da -1 girerek WxRuby'nin otomatik id üretmesini sağlayabilirsiniz.

title

Frame etiketi. Bir çok stilde frame üst kısmındaki barda gösterilir.

pos

Bir Wx::Point nesnesi boş bırakılırsa işletim sistemi bir yer belirler. Ekranın sol üst köşesi (0, 0) olarak düşünülerek frame'in ekrandaki yerini belirleyebilirsiniz.

size

Bir Wx::Size nesnesi frame'in ilk açılıştaki boyutunu tayin eder. Boş bırakılırsa default bir boyutla açılır.

style

Sabitlerden oluşan bir bitmask. Frame stilini belirler. Stil Sabitleri arasına | (bitwise or) işareti koyarak birçok stil sabiti kullanılabilir.

name

Frame'e verilen dahili isimdir. Daha sonra frame'i bulmak için kullanılabilir.


Frame stilleri sabitlerin birleşmesinden oluşmuştur. Örneğin DEFAULT_FRAME_STYLE şunlardan oluşur :

MAXIMIZE_BOX | MINIMIZE_BOX | RESIZE_BORDER |

SYSTEM_MENU | CAPTION | CLOSE_BOX

Bu birleşik stil içinden bir ya da birkaçını istemezsek özel veya ile çıkarabiliriz :

DEFAULT_FRAME_STYLE ^ ( RESIZE_BORDER | MINIMIZE_BOX | MAXIMIZE_BOX )


Tavsiye edilen üst seviye pencerede default stili kullanmaktır. Böyle olunca kullanıcı hangi pencerenin asıl olduğunu daha rahat anlar.


Stil

Açıklaması

CAPTION

Frame üzerine bir bar ekler buraya frame'in title parametresindeki string yazılır.

CLOSE_BOX

Frame etiket barına bir kapatma düğmesi ekler işletim sisteminden aynı şekliyle pencere kapatma düğmesi eklenir.

DEFAULT_FRAME_STYLE

Yukarda açıklamıştık.

FRAME_SHAPED

Bu stilde olan frame'ler set_shape metoduyla dikdörtgenden başka şekillerde olabilirler.

FRAME_TOOL_WINDOW

Frame'in toolbox penceresi olarak görünmesini sağlar. Daha küçük bir etiket barı olur sadece kapatma düğmesi olur ve görev yöneticide bu pencere görünmez.

MAXIMIZE_BOX

Pencereye tam ekran düğmesi ekler.

MINIMIZE_BOX

Pencereye aşağı küçültme düğmesi ekler.

RESIZE_BORDER

Pencerenin boyutu değiştirilebilir olmasını sağlar.

SIMPLE_BORDER

Gölgelendirmesiz düz ekran her işletim sisteminde çalışmaz.

SYSTEM_MENU

Pencereye system menüsü ekler. İlgili düğmelerin seçilmediği işlemler bu menüden de yaplamaz. (Tam ekran, minimize gibi)




Frame'e Widget Eklemek

Aşağıdaki programda frame ortasında bir buton konmuş ve butona tıklanınca uygulama sona eriyor.



1 #!/usr/bin/env ruby 
2 # Widget.rb Frame'e Buton Eklemek

3

4 require 'rubygems'

5 require 'wx'

6 include Wx

7

8 class InsertFrame < style="color: rgb(0, 0, 255);">
9 def initialize

10 super nil, -1, "Butonlu Frame", :size=>Size.new(300, 100)

11 panel = Panel.new self #1 Panel eklenmesi
12 button = Button.new panel, -1, "Close",
Point.new(125, 25), Size.new(60, 50) #2 Panele buton eklenmesi
13 evt_button(button) {on_close_me} #3 Butona tıklanınca

14 evt_close {on_close_window} #4 pencere kapanınca

15 end
16

17 def on_close_me
18 close

19 end

20

21 def on_close_window
22 destroy

23 end
24 end

25
26 class MyApp < style="color: rgb(0, 0, 255);">
27 def on_init

28 insert_frame = InsertFrame.new

29 insert_frame.show

30 end

31 end

32
33 if __FILE__ == $0
34 my_app = MyApp.new
35 my_app.main_loop

36 end
37

InsertFrame sınıfının iki alt window'u var. İlki panel, bu panel diğer windowları içine yerleştirmek için kullanılır. İkincisi de sıradan bir buton. Bunlar 1 ve 2 işaretli satırlarda gösterilmiştir. Daha sonra 3 nolu işaretli satırda butona tıklanınca çağırılacak kod bloğu tanıtılıyor. 4 nolu işaretli satırda pencere kapatma işlemi çağırılınca uygulmanın kapatılması için gerekli kod bloğu çağırılıyor.

Çoğu durumda frame içinde aynı boyutu kaplayacak bir panel koyarız ve diğer kontrolleri bu panel üzerine yerleştiririz. Ayrıca windows işletim sisteminde frame nesnesinin arkaplan rengi standart dışıdır ve gridir. Rengi beyaz olan bir panel ile daha güzel görüntü olacaktır. Ayrıca panel nesnesi içinde kontroller arasında tab butonu ile ezilebilir ama frame'de bu olmaz. Birçok diğer UI sistemlerde kontrol üretildikten sonra bir insert komutuyla ana taşıyıcıya eklenir. WxRuby de ise sadece kontrol üretilirken parent parmetresine taşıyıcı adı yazılır.

Ayrıca dikkat edersek buton için bir boyut girdik ve konacağı pozisyonu belirttik ama panel için böyle bir tanımlama yapmadık. WxRuby'de bir frame içine tek bir window yerleştirirsek (burada panel yerleştirilmiş, buton panelin içinde) bu window frame içinin tamamına otomatik olarak yayılır ve beraber boyut değiştirir. Panele boyut versek de bir şey değişmeyecekti. Ekrana konan her kontrole bir boyut vermek ve pencere boyutu değiştirilince olacaklara hükmetmek için rutinler yazmak oldukça zordur. Bunun için Sizer adı verilen nesneler kullanırız ama daha sonra açıklarız nasipse.



4 Aralık 2009 Cuma

WxRuby İlk Uygulama

Bu yazıda adım adım iş yapan bir uygulama yapacağız. Sonunda WxRuby logosu gösteren bir penceremiz olacak.
İlk önce WxRuby ile yazılabilecek en kısa uygulamayı yapalım. Minimum.rb adında bir dosya oluşturun ve aşağıdaki kodu girin :

 1 #!/bin/env ruby
2
3 require 'rubygems'
4 require 'wx'
5 include Wx
6
7 class App
8 def on_init
9 frame = Frame.new nil, -1, "Minimum"
10 frame.show
11 end
12 end
13
14 App.new.main_loop
Fazla bir şey yokmuş. 14 satırda ekrana boş bir pencere açtık. Bu programın asıl amacı WxRuby kurulumunuzun sağlıklı olduğunu görmek. Bu programı çalıştırmak için değişik işletim sistemlerinde değişik işlemler yapmak gerekebilir ama genellikle dosyanın olduğu klasörde terminal açılır ve şu yazılır :
ruby minimum.rb
Sonuçta şu görüntü ortaya çıkar :



Şimdi bu resme bakan birçok kişi bunu bir window olarak isimlendirebilir ama WxRuby'de bu bir Frame'dir. WxRuby'de Window görüntüsü olan herşeye verilen isimdir. Diğer kütüphanelerin çoğunda bunlara Widget denir. WxRuby'de Butonlar , TextBoxlar gibi şeyler Window olarak çağırılır.
Yazılan programda her satırın bir görevi vardır. Bu basit program her WxRuby programında bulunması gereken 5 öğeyi içerir:
  • Gerekli WxRuby kütüphanesini yüklemek.
  • WxRuby uygulama sınıfını tekrar işlemek.
  • Uygulama giriş metodunu tanımlamak.
  • Uygulama sınıfının bir oluşumunu üretmek.
  • Uygulamanın ana çevrimine girmek.
Şimdi adım adım her adımın nasıl gerçekleştirildiğini inceleyelim.



WxRuby Kütüphanesini Yüklemek

İlk yapmamız gereken wx adı verilen ana WxRuby kütüphanesini yüklemek.
  require 'wx'
include Wx

İlk satır 'wx' kütüphanesini yükler, ikinci satır ise kütüphaneden her çağırdığımız sınıfın başına 'Wx::' yazısını otomatik koyar yani bir Frame üretirken 'Wx::Frame.new' yerine 'Frame.new' yeterli olacaktır.


Uygulamalar ve Frame'ler ile Çalışmak

WxRuby kütüphanesini yükledikten sonra artık uygulamayı ve içinde Frame'i oluşturabiliriz. Her WxRuby uygulamasının mutlaka bir Application(uygulama) nesnesi ve enaz bir Frame nesnesi olur. Uygulama nesnesi Wx::App sınıfının bir oluşumudur veya alt sınıfıdır. Bu sınıfın 'on_init' metodu uygulama çalışınca çağırılır.

 class MyApp <>
def on_init
frame = Frame.new nil, -1, "Minimum"
frame.show
end
end

Şeklinde App sınıfının bir alt sınıfını tanımlamak genel eğilimdir. MyApp ismini biz verdik Ruby'de geçerli herhangi bir sınıf ismi olabilir. 'on_init' metodunda genellikle Frame tanımlamaları yapılır. Ama çoğunlukla burdaki gibi Frame sınıfı değil , MyFrame gibi bir altsınıf üretilerek kullanılır.

Frame'ler birçok parametre alır. Görünen ilk parametre mecburdur ama diğerlerini yazmasak da olur default değerleri vardır.

“Show” metodu frame'i görünür yapar. Eğer bu metodu kullanmazsak frame üretilir ama görünmez. Frame görünürlüğünü bir bool parametre vererek değiştirebiliriz:


frame.show false # frame görünmez olur.

frame.show true # true yazmasak da olur default true

frame.hide # bu da false parametre vermekle aynı işi yapar yani frame görünmez olur.


Son olarak uygulama sınıfının bir oluşumu üretilecek ve uygulamanın 'main_loop' metoduna girilecek. Bu şöyle de yapılabilir.


app = App.new

app.main_loop


Hepsi bu kadar! Bir kez uygulamanın main_loop metodunu çağırdıkmı artık kontrol WxRuby'ye geçer. Bu saatten sonra artık WxRuby kullanıcının eylemlerine cevap vermeye başlar. Yani mouse tıklamalarını , tuş basılmalarını izler. Uygulamanın tüm frame'leri kapanınca main_loop metodu da biter ve uygulama sona erer.


Minimum uygulamayı genişletmek

WxRuby'ye başlangıç yapabilmek için olabilecek en kısa kodlardan birini yazdık. Aslında standart bir uygulama yaparken bundan daha yapısal davranmak gerekir. Programı bölümlere ayırarak devam etmeliyiz. Aynı programı bir de yapısal olarak düzenlenmiş şekilde yazalım. Aşağıdaki programı yazıp spare.rb olarak kaydedin.

 1 #!/usr/bin/env ruby                             -1-
2 # Spare.rb WxRuby'ye giriş için yazılmıştır. -2-
3
4 require 'rubygems'
5 require 'wx'
6 include Wx
7
8 class MyFrame < Frame -3-
9
10 end
11
12 class MyApp < App
13 def on_init
14 frame = MyFrame.new nil , :title=> "Spare" -4-
15 frame.show
16 end
17 end
18
19 if __FILE__ == $0 -5-
20 my_app = MyApp.new
21 my_app.main_loop
22 end

1 numaralı işaretin olduğu ilk satır bir shebang satırı. Bir Ruby yorum satırına benziyor, gerçekte de öyle ama linux gibi bazı işletim sistemlerinde shebang satırı işletim sistemine bu betiği çalıştırmak için kullanacağı interpreter'ı tarif eder. Bu sayede linuxta sadece komut satırında dosyanın adını yazarak çalıştırabiliriz. Yani “ruby spare.rb” yerine sadece “spare.rb” yazdığımızda betik çalışması için ruby interpreter gerektiği bilinir. Kullanıcıların ruby işini bilmelerine gerek yok sadece dosyanın adını yazdıklarında betik çalışır. Bu satır kullanılmadığı işletim sistemlerinde Bir şey ifade etmez ama cross platform uygulamalar yazmak için bu satırı koymamız gerekir.


2- nolu işaretli satırda uygulamanın Ruby dökümanı için bir dökümantasyon yorumu yazdık. İlerde bu uygulamanın rdoc ile dökümanı çıkarıldığında dökümana uygulamanın açıklaması olarak bu yorum gelecektir. Benzer şekilde her sınıf tanımından ya da metod tanımından önce gelen satırda yazılan yorumlar o metod ya da sınıfın rdoc dökümanında açıklama olarak gelir. Bundan başka rdoc dökümanının görüntüsünü wiki benzeri formatlayan yöntemler vardır.


3- Frame sınıfının bir altsınıfını kendi MyFrame sınıfımız olarak tanıttık, şimdilik hiçbir şeyi değiştirmedik. İlerde içinde butonlar textboxlar vb. olan frame tanımlamaları yapacağız. Programınızın frame'i karmaşıklaşmaya başladığında ya da birden fazla frame içeren programlar yaparken bu şekilde her frame için bir altsınıf tanımlaması yapmak programınızın anlaşılabilir olmasına yardımcı olacaktır.


4- Uygulama sınıfı içinde kendi frame sınıfımızı parametrelerle çağırıyoruz. Kendi sınıfımızın tanımında başka bir şekil belirtilmediği için Wx::Frame sınıfı ile aynı şekilde parametreleri değerlendirilir. Bir nesneden üretilen nesne yine nesnedir ve aynı şekilde parametreler alır.


5- Son bölüm bir ruby programında kullanılan genel yapılardan biridir. Bir betik iki şekilde kullanılır, ya direk olarak çalıştırılır ya da başka bir betik içine kütüphane dosyası olarak “require” ile çağırılır. Bir betiği kütüphane olarak çağırdığımızda onun içindeki sınıfları ve metodları kullanırız. Eğer bu betik tek başına çalışan bir betikse mesela bir pencere açıyorsa require komutu sonrası da çalışmaya kalkar, halbuki biz sadece içindeki sınıfları ve metodları kullanmak istiyoruz. Burdaki kalıbı kullanarak çalışmasını istemediğimiz kodları ayırıyoruz. “__FILE__” değişkeni kodun bulunduğu dosyanın adını verir, yani burada “spare.rb” değeri alır. “$0” ise aktif iş yapan betiğin adıdır. Şimdi eğer “ruby spare.rb” deyip direk bu betik çalıştırılırsa “$0” değişkeni de “spare.rb” değerini alır yani “__FILE__” değişkeni ile aynı olur. Ama diyelim bu betiği “app.rb” adındaki başka bir betiğin içinde “require spare.rb” deyip yüklediğimizde “$0” değişkeni artık “app.rb” olacaktır bu durumda if satırı içindeki kodlar çalışmayacak sadece sınıf tanımlamaları diğer betiğe yüklenecektir. Bunu yapmasaydık require ile betiği başka bir betik içine yüklemeye kalktığımızda uygulama çalışıp frame açılacaktı.


En Son Hello.rb Betiğin Üretilmesi

Şimdi artık son haline getirelim. “hello.rb” adındaki betiğe aşağıdaki satırları girelim :

 1 #!/usr/bin/env ruby
2 # Merhaba WxRuby Prgramı !
3
4 require 'rubygems'
5 require 'wx'
6 include Wx
7
8 # MyFrame bir resim gösteriyor.
9 class MyFrame < Frame
10 # Bir Frame oluşumu yap ve bir resim göster
11 def initialize(image, parent=nil, id=-1, pos=DEFAULT_POSITION, title="Merhaba WxRuby" )
12 temp = image.convert_to_bitmap
13 size = Size.new(temp.get_width, temp.get_height)
14 super parent, id, title, pos, size
15 bmp = StaticBitmap.new self, :label=>temp
16 end
17 end
18
19 # Uygulama Sınıfı
20 class MyApp < App
21 def on_init
22 image = Image.new "wxruby.png", BITMAP_TYPE_PNG
23 frame = MyFrame.new image
24 frame.show
25 end
26 end
27
28 if __FILE__ == $0
29 my_app = MyApp.new
30 my_app.main_loop
31 end
32
33
34

İlk satır shebang satırı, bu satırla Linux işletim sisteminde betik sadece adı yazılıp çalıştırılabiliyor. Frame sınıfının altsınıfını tanımlayarak frame yerleşimini ve kontrolünü daha rahat yapıyoruz. Kendi Frame sınıfımızın üretilmesine orjinalinden ayrı olarak “image” adında bir parametre daha ekliyoruz. Diğer parametreler için default değerler vererek sadece bu parametrenin yeterli olmasını sağlıyoruz. Resmimizi bir StaticBitmap içinde göstereceğiz. Bu resim boyutlarını alıp Frame nesnemizi üretirken tam bu resmi kapsayacak büyüklükte olmasını sağlıyoruz. Sonra Uygulama sınıfının bir alt sınıfını ve on_init metodunu tanımlıyoruz. Bir Image nesnesi üretip web sitesinden indirdiğimiz “wxruby.png” resmini be nesneye yüklüyoruz. Daha sonra standart bir kontrol yapıyoruz , bu betik komut satırından mı çağırıldı yoksa başka bir betik içine mi çağırıldı ?










1 Aralık 2009 Salı

WxRuby Girişi

#!/bin/env ruby

require 'rubygems'
require 'wx'
include Wx

class MyFrame < Frame
def initialize
super nil, -1, "My Frame", :size=>Size.new(300, 300)
panel = Panel.new self, -1
panel.evt_motion {|event|on_move(event)}
StaticText.new panel, -1, "Pos : ", :pos=>Point.new(10, 12)
@pos_ctrl = TextCtrl.new panel, -1, :pos=>Point.new(50, 10)
end

def on_move(event)
pos = event.get_position
@pos_ctrl.set_value "#{pos.x}, #{pos.y}"
end
end

if __FILE__ == $0
app = Wx::App.new
def app.on_init
frame = MyFrame.new
frame.show
end
app.main_loop
end


Bu program çok az bir kodla görsel bir iş yapıyor. Bir pencere açıyor, mouse hareketini takip edip sonucu ekrana yazıyor.



30 satırlık bir program için hiç fena değil. Diğer dillerden birçoğunda bunun 3-4 katı program yazılması gerekirdi. Programcılıkla biraz ilginiz varsa Ruby bilmeseniz bile satırları incelediğinizde biraz anlaşılabilir. Tüm argümanları tahmin edemeyebilirsiniz (mesela '-1' ler ne oluyor?) ama kaba bir fikir sahibi olabilirsiniz.
WxRuby kullanarak hem Ruby dilinin kolaylıklarından hem WxWidgets GUI kütüphanesinin geniş kapsamından yararlanarak masaüstü uygulamala geliştirebilirsiniz.