https://ujk-ujk.blogspot.com/2025/03/wxruby3-ile-masaustu-uygulama.html
Selam Ruby ile masaüstü program yazmak üzerine neler yapabilirim bir göreyim dedim ve başladım denemelere. Denemelerimi Windows'ta yaptım. Windows üzerinde bende kurulu olan versiyon ruby 3.4.2 (2025-02-15 revision d2930f8e7a) +PRISM [x64-mingw-ucrt] olarak geliyor. Ruby installer sitesinden Ruby+Devkit 3.4.2-1 (x64) versiyonu indirip kurdum.
WxRuby3 Kurulumu
WxRuby3 GUI kütüphanesini yüklemek için komut isteminde
gem install wxruby3
komutunu girdim ve sıkıntısız yüklendi. Sizde sorun olurssa bendeki versiyon Ruby ile deneme yaparsınız.
Hemen deneme yapmak için hello.rb adında bir dosya üretip içine şu kodu yazdım.
require 'wx'
Wx::App.run { puts 'Merhaba Dünya!' }
Aslında bu kod pek bir şey yapmıyor, eğer çalışırsa konsola Merhaba Dünya! yazıp bitiyor. Bu programın amacı WxRuby kütüphanesi kullanımının başarılı olduğunu görmek. Programı incelersek
require 'wx' komutu kurduğumuz WxRuby3 Gem dosyalarının programımızda kullanılacağını belirtiyor.
Wx::App sınıfı , ana Wx programı sınıfı. Bu sınıfın run metodunu çağırarak Wx uygulaması çalıştırılıyor. run metoduna verilen blok içindeki program bir Wx uygulaması olarak çalıştırılıyor. Dökümanına bakarsak run metodu Wx::App sınıfının bir oluşumunu üretiyor ve verilen kod bloğunu da bu nesnenin #on_init olayına bağlıyor, Yani nesne üretilince bloktaki kod çalışıyor.
Şimdi bir pencere üreterek ekranımızda gösteren bir kod yazalım bloğun içine.
require 'wx'
Wx::App.run { Wx::Frame.new(nil, title: 'Merhaba Dünya!').show }
Bu kod jenerik bir Frame (pencere) nesnesi üretiyor ve onun show metodunu çağırıyor. new metodunun ilk argümanı nil olarak verilmiş , bu Frame nesnesinin parent değeri. Bu değerin nil olması penceremizin bağımsız bir pencere olduğunu gösteriyor. Eğer buraya bir Wx::Window nesnesi beliritilirse penceremiz o nesneyle beraber minimize ve restore olacakmış (tabi kendi bağımsız olarak minimize de edilebilecek). İkinci argüman ise isimlendirilmiş olarak :title değerini belirtiyor, adından da anlaşılabileceği gibi pencere etiketinde yazan yazıyı belirliyor. İlerleyen zamanda başka argümanlar da kullanacağız.
show metodu uygulandığı pencereyi göstermek (ya da gizlemek) için kullanılıyor.
Şimdi programı çalıştıralım.

Karşımıza default boyutta ve default pozisyonda bir pencere açılacaktır.
Uygulama sınıfı tanımlamak
Daha karmaşık uygulamalar yazarken Wx::App sınıfından türetilmiş kendi sınıfımızı tanımlamak çok daha faydalı olacaktır. Bu sayede #initialize, #on_init ve #on_exit metodlarının üzerine yazarak istediğimiz davranışı göstermesini yönetebiliriz.
hello2.rb
require 'wx'
class MyApp < Wx::App
def initialize
super
@frame = nil
end
attr_reader :frame
# run deyince çalışacak
def on_init
@frame = Wx::Frame.new(nil, title: 'Merhaba Dünya!')
@frame.show
end
# pencereyi kapatınca çalışacak
def on_exit
puts 'Çıkıyoruz.'
end
end
MyApp.run
Burada #on_init ve #on_exit metodlarının üzerine yazılmıyor, orjinal Wx::App sınıfında bu metodlar yok. Bu yüzden tanımlamalarında super ifadesi kullanılmıyor.
Eğer sınıfta on_init tanımlı değilse run metodu argümanında verilen blok çalıştırılır. Eğer on_init metodu tanımlanmışsa (ki bizim ürettiğimiz sınıfta mevcut) o zaman run metodu bu on_init metodunu çalıştıracaktır. Bu yüzden kod bloğu bermeden sadece MyApp.run demek yeterli olmuştur.
Uygulamanın oluşum nesnesine uygulama hala aktifken
Wx.get_app
olarak erişebiliriz.
Pencere sınıfı tanımlamak
Kendi pencere sınıfımızı tanımlayıp onu da kullanabiliriz. Böylece pencere içindeki elemanları daha düzenli kodlayabiliriz.
hello3.rb
require 'wx'
class TheFrame < Wx::Frame
def initialize(title)
super(nil, title: title)
panel = Wx::Panel.new(self)
button = Wx::Button.new(panel, label: 'Bana Tıklayınız')
button.evt_button(Wx::ID_ANY) do
Wx.message_box('Merhaba. Bana tıkladığın için teşekkürler!',
'Buton olayı')
end
end
end
class MyApp < Wx::App
def initialize
super
@frame = nil
end
attr_reader :frame
# run deyince çalışacak
def on_init
@frame = TheFrame.new('Merhaba Dünya!')
@frame.show
end
# pencereyi kapatınca çalışacak
def on_exit
puts 'Çıkıyoruz.'
end
end
MyApp.run
ve çıktısı

Wx::Frame
Wx::Frame sınıfı oluşum kodu kalıbı
Wx::Frame.new(parent, id, title, pos = Wx::DEFAULT_POSITION,
size = Wx::DEFAULT_SIZE, style = Wx::DEFAULT_FRAME_STYLE,
name = Wx::FRAME_NAME_STR)
id : Pencereyi simgeleyen sayı , default -1
pos (Array(Integer, Integer), Wx::Point) : Pencrenin sol üst köşesinin ekrana göre pozisyonu - x, y
frame = Wx::Frame.new(nil, pos: [150, 50])
size (Array(Integer, Integer), Wx::Size) : Pencere boyutu - genişlik, yükseklik
frame = Wx::Frame.new(nil, size: [400, 200])
style (Integer) : Bir çok flag bitlerinden oluşan stil sayısı default olarak
MINIMIZE_BOX | MAXIMIZE_BOX | RESIZE_BORDER | SYSTEM_MENU | CAPTION |
CLOSE_BOX | CLIP_CHILDREN
Örnek :
no_minimize.rb
require "wx"
Wx::App.run {
Wx::Frame.new(nil,
style: Wx::MAXIMIZE_BOX | Wx::RESIZE_BORDER |
Wx::SYSTEM_MENU | Wx::CAPTION | Wx::CLOSE_BOX).show
}
Boyut ve Pozisyon
Pencere boyutunu iki şekilde belirtiriz. Ya pencereyi oluştururken ya da sonradan set_size metodunu çağırarak.
set_size.rb
require "wx"
class Örnek < Wx::Frame
def initialize(parent, title)
super(parent, title: title,
size: [350, 250])
end
end
Wx::App.run {
Örnek.new(nil, 'Boyutlandırma').show
}
Sonradan boyutlandırırsak
require "wx"
class Örnek < Wx::Frame
def initialize(parent, title)
super(parent, title: title)
end
end
Wx::App.run {
p = Örnek.new(nil, 'Boyutlandırma')
p.set_size 100,200,350,250
p.show
}
# x=100 - y=200 - w=350 - h=250
ya da pozisyon belirtmeden
p.set_size [350, 250]
Pencereyi istediğimiz yere kaydırabiliriz.
move.rb
require "wx"
class Örnek < Wx::Frame
def initialize(parent, title)
super(parent, title: title,
size: [300, 200])
move [800, 200]
end
end
Wx::App.run {
Örnek.new(nil, 'Kaydırma').show
}
Ekranı Ortalamak
Pencerenin ekranı ortalaması için centre metodunu kullanırız.
merkezleme.rb
require "wx"
class Örnek < Wx::Frame
def initialize(parent, title)
super(parent, title: title,
size: [300, 200])
centre
end
end
Wx::App.run {
Örnek.new(nil, 'Ortalama').show
}
Yatay ya da dikey olarak da ortalamak mümkün.
centre Wx::Orientation::VERTICAL
centre Wx::Orientation::HORIZONTAL
Menüler, Toolbarlar
Bir GUI uygulamasının temel öğelerinden biri menülerdir. Bir MenuBar nesnesi içinde Menu nesneleri barındırır.
Basit Menü
simple_menu.rb
require "wx"
class Örnek < Wx::Frame
def initialize(*args)
super(*args)
init_UI
end
def init_UI
set_size [300, 200]
set_title "Basit Menü"
centre
menubar = Wx::MenuBar.new
file_menu = Wx::Menu.new
file_item = file_menu.append(Wx::ID_EXIT, "&Çıkış", "Uygulamadan çıkış")
menubar.append file_menu, "&Dosya"
set_menu_bar menubar
evt_menu(file_item) { close }
end
end
Wx::App.run {
Örnek.new(nil).show
}

Önce bir MenuBar nesnesi oluşturuyoruz. menubar = Wx::MenuBar.new
Sonra üzerine eklemek için bir Menu nesnesi ekliyoruz. file_menu = Wx::Menu.new
Menu nesnesine eleman ekliyoruz (popup içinde görünen) file_item = file_menu.append(Wx::ID_EXIT, "&Çıkış", "Uygulamadan çıkış")
& karakteri hangi harfin önüne gelirse Alt tuşuna basıldığında o harfin altı çizili olur (tuşlar ile menü seçme standardı)
Daha sonra Menu nesnemizi MenuBar nesnemize başlığını belirterek ekliyoruz. menubar.append file_menu, "&Dosya"
Son olarak Frame#set_menu_bar metodu ile MenuBar nesnemizi penceremize ekliyoruz. set_menu_bar menubar
Eklediğimiz menüye tıklanınca ne olacağını da evt_menu olay işleme metoduna verdiğimiz kod bloğunda belirtiyoruz. evt_menu(file_item) { close }
Burada tıklanınca Frame#close metodu çağrılıyor, yani pencere kapatılıp uygulama bitiriliyor.
İkonlar ve kısayollar
Sıradaki örneğimiz temelde önceki ile aynı, ancak bu sefer Wx::MenuItem oluşum nesnesini elle oluşturacağız.
icons_shortcuts.rb
require "wx"
class Örnek < Wx::Frame
def initialize(*args)
super(*args)
init_UI
end
def init_UI
set_size [300, 200]
set_title "İkonlar ve Kısayollar"
centre
menubar = Wx::MenuBar.new
file_menu = Wx::Menu.new
qmi = Wx::MenuItem.new(file_menu, Wx::ID_EXIT, "&Çıkış\tCTRL+Q")
qmi.set_bitmap(Wx::Bitmap.new('exit_16.png'))
file_menu.append qmi
menubar.append file_menu, "&Dosya"
set_menu_bar menubar
evt_menu(Wx::ID_EXIT) { close }
end
end
Wx::App.run {
Örnek.new(nil).show
}
qmi nesnesini oluştururken standart Wx::ID_EXIT id değerini kullandık. Wx::StandardID sınıfında tanımlı birçok hazır ID değeri var. Kendimizde bir sayı girebiliriz ama karışıklık olmasın diye hazırlardan işimize uyan varsa onu kullanmak daha iyidir.
Logo için resim dosyasını internetten bulup koydum.
Olay işleyici satırına
evt_menu(qmi) { close }
de yazsak çalışır, id de versek çalışır. "&Çıkış\tCTRL+Q" değeri tuş takımı yardımıyla Alt+d+ç kombinasyonu ile çıkabileceğimiz gibi, hiç menü açmadan Ctrl+q basarak da uygulamadan çıkabiliriz. \t ile kısayol tuşu bildiriliyor.

Alt menü ve seperatörler
Her menüde alt menüler de olabilir. Bir de mesela Yeni Aç, Kaydet gibi menü elemanları ile Çıkış elemanı arasına bir ayırıcı (separator) koysak iyi olur.
submenu.rb
require "wx"
class Örnek < Wx::Frame
def initialize(*args)
super(*args)
init_UI
end
def init_UI
set_size [350, 250]
set_title "Alt Menü"
centre
menubar = Wx::MenuBar.new
file_menu = Wx::Menu.new
file_menu.append Wx::ID_NEW, '&Yeni'
file_menu.append Wx::ID_OPEN, '&Aç'
file_menu.append Wx::ID_SAVE, '&Kaydet'
file_menu.append_separator
imp = Wx::Menu.new
imp.append Wx::ID_ANY, "Haber listesi al..."
imp.append Wx::ID_ANY, "Yer imlerini al..."
imp.append Wx::ID_ANY, "Eposta al..."
file_menu.append_sub_menu imp, "I&mport"
file_menu.append Wx::ID_EXIT, "&Çıkış\tCTRL+Q"
menubar.append file_menu, "&Dosya"
set_menu_bar menubar
evt_menu(Wx::ID_EXIT) { close }
end
end
Wx::App.run {
Örnek.new(nil).show
}
Alt menümüz yine bir Wx::Menu nesnesi ve üst menüye append_sub_menu metodu ile ekleniyor. İlk argüman eklenecek olan Wx::Menu nesnesi ikinci de menü başlık yazısı.
Ayrıcı eklemek içinse append_separator metodu kullanılıyor.

İstersek hazır bulunan ikonları menülere ekleyebiliriz.
file_menu.append(Wx::ID_NEW, '&Yeni').
set_bitmap(Wx::ArtProvider.get_bitmap(Wx::ART_NEW))
file_menu.append(Wx::ID_OPEN, '&Aç').
set_bitmap(Wx::ArtProvider.get_bitmap(Wx::ART_FILE_OPEN))
file_menu.append(Wx::ID_SAVE, '&Kaydet').
set_bitmap(Wx::ArtProvider.get_bitmap(Wx::ART_FILE_SAVE))
Dökümanda sabitler listesinde ART_ ile başlayan sabitleri deneyebilirsiniz.

Checkbox menü elemanı
3 çeşit menü elemanı vardır.
- normal eleman
- check eleman
- radio eleman
Aşağıdaki örnekte check menü elemanı görülüyor. Check menü tiklenebilir bir menü elemanı görüntüsü verir.
checkmenu_item.rb
require "wx"
class Örnek < Wx::Frame
def initialize(*args)
super(*args)
init_UI
end
def init_UI
set_size [350, 250]
set_title "Check Menü Elemanı"
centre
toolbar = create_tool_bar
toolbar.add_tool Wx::ID_EXIT, "",
Wx::ArtProvider.get_bitmap(Wx::ART_QUIT)
toolbar.realize
statusbar = create_status_bar
statusbar.set_status_text "Ready"
menubar = Wx::MenuBar.new
view_menu = Wx::Menu.new
shst = view_menu.append Wx::ID_ANY, "Durum çubuğunu göster",
"Araç çubuğunu göster", Wx::ITEM_CHECK
shtl = view_menu.append Wx::ID_ANY, "Araç çubuğunu göster",
"Araç çubuğunu göster", Wx::ITEM_CHECK
view_menu.check shst.id, true
view_menu.check shtl.id, true
menubar.append view_menu, "&Görünüm"
set_menu_bar menubar
evt_menu(shst) { shst.checked? ? statusbar.show : statusbar.hide }
evt_menu(shtl) { shtl.checked? ? toolbar.show : toolbar.hide }
evt_menu(Wx::ID_EXIT) { close }
end
end
Wx::App.run {
Örnek.new(nil).show
}
Görünüm menümüzün içine iki tane check menü elemanı ekledik. Bu iki menü elemanı ile durum çubuğu ve araç çubuğunu gösterip gizliyoruz.
shst = view_menu.append Wx::ID_ANY, "Durum çubuğunu göster",
"Araç çubuğunu göster", Wx::ITEM_CHECK
shtl = view_menu.append Wx::ID_ANY, "Araç çubuğunu göster",
"Araç çubuğunu göster", Wx::ITEM_CHECK
view_menu nesnemizin append metodu ilk iki parametresini daha önce kullandık, id numarası ve menüde yazan yazı. Üçüncü parametre yardım yazısı, dördüncü ise kind (yani tür) bilgisi. Dördüncü argümanda Wx::ITEM_CHECK girerek menü elemanının bir tiklemeli menü elemanı olduğunu bildiriyoruz. Sonrasında
view_menu.check shst.id, true
view_menu.check shtl.id, true
satırları ile her iki menü elemanının da başlangıçta tiklenmiş olarak gelmesini sağlıyoruz. Bu arada deneme yapalım derken basit de olsa durum ve araç çubuğu eklemesini de gördük .
Menülere tıklanınca yapılacaklar
evt_menu(shst) { shst.checked? ? statusbar.show : statusbar.hide }
evt_menu(shtl) { shtl.checked? ? toolbar.show : toolbar.hide }
satırlarındaki olay işleme kodları ile belirleniyor. checked? metodu menü elemanının o anda seçili olup olmadığını test ediyor. show ve hide metodları ise hemen tüm kontrollerdeki gibi uygulandığı nesnenin görünmesi ya da gizlenmesini sağlıyor.

Bağlamsal menüler
Bağlamsal menü (context menu) değişik bağlamlarda değişik menülerin açılması şeklinde oluşan menülerdir. Örneğin tarayıcınızda sayfa içine sağ tıklarsanız başka menü, adrese sağ tıklarsanız başka bir menü, pencere başlığına tıklayınca başka bir menü açılır. Bunlara bazen popup menü de denir.
context_menu.rb
require "wx"
class MyPopupMenu < Wx::Menu
def initialize(*args, parent)
super(*args)
@parent = parent
mmi = Wx::MenuItem.new(self, Wx::ID_ANY, 'Minimize')
append mmi
evt_menu(mmi) { on_minimize }
cmi = Wx::MenuItem.new(self, Wx::ID_ANY, 'Kapat')
append cmi
evt_menu(cmi) { on_close }
end
def on_minimize
@parent.iconize
end
def on_close
@parent.close
end
end
class Örnek < Wx::Frame
def initialize(*args)
super(*args)
init_UI
end
def init_UI
set_size [350, 250]
set_title "Bağlamsal Menü"
centre
evt_right_down { |e| on_right_down(e) }
end
def on_right_down(e)
popup_menu MyPopupMenu.new(self), e.get_position
end
end
Wx::App.run {
Örnek.new(nil).show
}
Öncelikle Wx::Menu sınıfından kendi MyPopupMenu sınıfımızı üretiyoruz.
mmi = Wx::MenuItem.new(self, Wx::ID_ANY, 'Minimize')
append mmi
evt_menu(mmi) { on_minimize }
Bu satırlarla menümüze yeni bir menü elemanı ekliyoruz. Olay işlemeyi eğer kod bloğu içinde yapmayacaksak dışarıdan başka bir oluşum metodu da çağırabiliriz.
evt_right_down { |e| on_right_down(e) }
end
def on_right_down(e)
popup_menu MyPopupMenu.new(self), e.get_position
end
Burada görülense dışarıdan çağrılan metoda olay bilgisini içeren bir nesne göndermek. Frame üzerinde sağ tıklanan yeri bulmak için get_position metodu ile olay bilgisinden çekiyoruz, ve popup orada açıyoruz.
Şimdi çalıştırıp pencere içinde bir yere sağ tıklarsak.

Araç Kutuları
Menülerde bir hiyerarşi içinde uygulamamıza gerekli tüm işlemleri menülerimizde toplarız. Araç kutularında ise çok kullanılan bazı işlemleri hızlıca erişilebilir biçimde penceremize koyarız. Wx::Frame nesnesinde araç kutusu oluşturmak için create_tool_bar metodunu çağırırız.
toolbar.rb
require "wx"
class Örnek < Wx::Frame
def initialize(*args)
super(*args)
init_UI
end
def init_UI
set_size [350, 250]
set_title "Basit Araç Kutusu"
centre
toolbar = create_tool_bar
qtool = toolbar.add_tool Wx::ID_EXIT, "Çıkış",
Wx::ArtProvider.get_bitmap(Wx::ART_QUIT)
toolbar.realize
evt_menu(qtool) { close }
end
end
Wx::App.run {
Örnek.new(nil).show
}
Örnekte araç kutumuzda bir tane araç butonu var ve uygulamadan çıkılmasını sağlıyor.
toolbar = create_tool_bar
Araç kutumuzu üretir. Default olarak araç kutumuz yatay olur, sınır çizgileri yoktur ve ikonlar gösterir.
qtool = toolbar.add_tool Wx::ID_EXIT, "Çıkış",
Wx::ArtProvider.get_bitmap(Wx::ART_QUIT)
Bu satır da bir araç butonu ekliyor. add_tool metodu ilk parametresi id değeri, ikinci ise etiket yazısı (ki bu yazı görünmez), üçüncüsü de butondaki resim.
toolbar.realize
Bütün araç butonlarımız bittikten sonra realize metodu ile aktif hale getiriyoruz.

Eğer bir'den fazla araç kutusu olacaksa farklı davranmak gerekir.
toolbars.rb
require "wx"
class Örnek < Wx::Frame
def initialize(*args)
super(*args)
init_UI
end
def init_UI
set_size [350, 250]
set_title "Araç Kutuları"
centre
vbox = Wx::VBoxSizer.new
toolbar1 = Wx::ToolBar.new(self)
toolbar1.add_tool Wx::ID_NEW, "",
Wx::ArtProvider.get_bitmap(Wx::ART_NEW)
toolbar1.add_tool Wx::ID_OPEN, "",
Wx::ArtProvider.get_bitmap(Wx::ART_FILE_OPEN)
toolbar1.add_tool Wx::ID_SAVE, "",
Wx::ArtProvider.get_bitmap(Wx::ART_FILE_SAVE)
toolbar1.realize
toolbar2 = Wx::ToolBar.new(self)
toolbar2.add_tool Wx::ID_EXIT, "",
Wx::ArtProvider.get_bitmap(Wx::ART_QUIT)
toolbar2.realize
vbox.add toolbar1, 0, Wx::EXPAND
vbox.add toolbar2, 0, Wx::EXPAND
set_sizer vbox
evt_tool(Wx::ID_EXIT) { close }
end
end
Wx::App.run {
Örnek.new(nil).show
}
Bu örnekte iki tane yatay araç kutusu üretiyoruz.
toolbar1 = Wx::ToolBar.new(self)
...
toolbar2 = Wx::ToolBar.new(self)
Bu iki araç kutusunu dikey bir yerleşim yardımcısına yerleştirdik.

Aktif-Pasif araç butonları
Aşağıdaki örnekte araç butonlarının aktif veya pasif olmasını göreceğiz. Ayrıca araç kutumuza bir ayırıcı da ekleyeceğiz.
undo_redo.rb
require "wx"
class Örnek < Wx::Frame
def initialize(*args)
super(*args)
init_UI
end
def init_UI
set_size [350, 250]
set_title "Undo Redo"
centre
@count = 5
vbox = Wx::VBoxSizer.new
@toolbar = create_tool_bar
tundo = @toolbar.add_tool Wx::ID_UNDO, "",
Wx::ArtProvider.get_bitmap(Wx::ART_UNDO)
tredo = @toolbar.add_tool Wx::ID_REDO, "",
Wx::ArtProvider.get_bitmap(Wx::ART_REDO)
@toolbar.enable_tool Wx::ID_REDO, false
@toolbar.add_separator
texit = @toolbar.add_tool Wx::ID_EXIT, "",
Wx::ArtProvider.get_bitmap(Wx::ART_QUIT)
@toolbar.realize
evt_tool(Wx::ID_UNDO) { on_undo }
evt_tool(Wx::ID_REDO) { on_redo }
evt_tool(Wx::ID_EXIT) { close }
end
def on_undo
if @count > 1 and @count <= 5
@count -= 1
end
if @count == 1
@toolbar.enable_tool Wx::ID_UNDO, false
end
if @count == 4
@toolbar.enable_tool Wx::ID_REDO, true
end
end
def on_redo
if @count < 5 and @count >= 1
@count += 1
end
if @count == 5
@toolbar.enable_tool Wx::ID_REDO, false
end
if @count == 2
@toolbar.enable_tool Wx::ID_UNDO, true
end
end
end
Wx::App.run {
Örnek.new(nil).show
}
Uygulamamızda 3 tane araç butonu ekledik , biri uygulamadan çıkmak için diğerleri de undo-redo (geri al - yinele) işlemlerini simüle etmek için.
@toolbar.enable_tool Wx::ID_REDO, false
@toolbar.add_separator
İlk başta redo butonu pasif durumda olacak , pasif yapmak için enable_tool metodunu kullanıyoruz. Araç butonu gruplarını birbirinden ayırmak için add_separator metodunu kullanıyoruz. Bu bazı işletim sistemlerinde bir çizgi eklerken mesela bende sadece butonlar arasını biraz boşlukla açıyor.
def on_undo
if @count > 1 and @count <= 5
@count -= 1
end
if @count == 1
@toolbar.enable_tool Wx::ID_UNDO, false
end
if @count == 4
@toolbar.enable_tool Wx::ID_REDO, true
end
end
Undo ve redo işlemlerinin simülasyonunu yapıyoruz. 4 tane değişimimiz varmış ve geri alacak bir şey kalmayınca undo butonu pasif oluyor. İlk değişikliği geri alınca redo butonunu aktif ediyoruz. Benzer lojik redo butonu için de geçerli.

Bu bölümde WxRuby3 uygulama geliştirmede menüleri ve araç kutularını inceledik. Pencere yerleşimi ile devam edelim.
WxRuby'de Yerleşim Yönetimi
Tipik bir uygulamada birçok widget bulunur (ben bunlara 'zımbırtı' diyorum, bazen 'kontrol' dendiği de olur). Bu widget'lar başka barındırıcı widget'lar içine konarak yerleşimleri yönetilir. Wx kütüphanesinde yerleşimi sabit pozisyonlama ile ya da boyutlandırıcılar ile yönetmek mümkün, ve bu biraz karmaşık bir iş.
Mutlak pozisyonlama
Programlayıcı her kontrolün yerleşeceği yeri ve boyutlarını piksel olarak bildirir. Mutlak pozisyonlamanın bazı dezavantajları vardır.
- Pencere boyutu değişince kontrollerin boyutu ve yerleşimi orantılı olarak değişmez. Bu yüzden genellikle boyutu değiştirilemeyen bilgilendirme pencerelerinde falan kullanılır.
- Değişik işletim sistemlerinde (ve hatta ayarları değişik olan aynı sistemlerde bile) farklı görünen uygulamalar oluşur.
- Uygulamanızda yazı font'unu değiştirmek yerleşimde bozulmalara sebep olabilir.
- Yerleşimi değiştirmeye karar verdiğimizde tüm yerleşimi elden geçirmemiz gerekir ki bu hem sıkıcı hem de yorucu olur.
Bazen , mesela denemeler yaparken , mutlak pozisyonlama ile hızlıca deneme yapabiliriz. Ancak gerçek dünya uygulamaları, boyutlandırıcıların kullanılmasını gerektirir.
Uygulama örneğimizde resimler olacak ve pencere boyutu değiştirilince resimlerin pozisyonunun otomatik değişmediğini göreceğiz.
absolute.rb
require "wx"
class Örnek < Wx::Frame
def initialize(*args)
super(*args)
init_UI
end
def init_UI
set_size [350, 300]
set_title "Mutlak Pozisyonlama"
centre
@panel = Wx::Panel.new(self)
@panel.background_colour = "gray"
load_images
@mincol.position = [20, 20]
@bardejov.position = [40, 160]
@rotunda.position = [170, 50]
end
def load_images
@mincol = Wx::StaticBitmap.new(@panel, Wx::ID_ANY,
Wx::Bitmap.new("mincol.jpg", Wx::BITMAP_TYPE_ANY))
@bardejov = Wx::StaticBitmap.new(@panel, Wx::ID_ANY,
Wx::Bitmap.new("bardejov.jpg", Wx::BITMAP_TYPE_ANY))
@rotunda = Wx::StaticBitmap.new(@panel, Wx::ID_ANY,
Wx::Bitmap.new("rotunda.jpg", Wx::BITMAP_TYPE_ANY))
end
end
Wx::App.run {
Örnek.new(nil).show
}

Boyutlandırıcı kullanmak
Boyutlandırıcılar mutlak pozisyonlama için verdiğimiz tüm dezavantajları halleder. WxRuby kütüphanesinde şu boyutlandırıcılar var.
- Wx::BoxSizer
- Wx::StaticBoxSizer
- Wx::GridSizer
- Wx::FlexGridSizer
- Wx::GridBagSizer
Wx::BoxSizer
Wx::BoxSizer boyutlandırıcı içine kontrollerimizi yatay ya da dikey olarak sıralayabiliriz. Karmaşık yerleşimler oluşturmak için bir boyutlandırıcı içine diğerini koyarak kombinasyonlar üretebiliriz.
box = Wx::BoxSizer(integer orient)
box.add(Wx::Window window, integer proportion=0,
integer flag=0, integer border=0)
Yeni boyutlandırıcı tanımlarken verilen orient parametresi yatay ya da dikey yerleşim için kullanılacağını belirtir. Buraya Wx::VERTICAL veya Wx::HORIZONTAL girilir. Boyutlandırıcıya bir kontrol eklemek için add metodunu kullanırız. Parametrelere bir bakalım.
proportion parametresi eklenen kontrolün boyutlandırıcının verilen yönünde nasıl yayılacağını ve boyutlandırıcı boyutu değişince nasıl davranacağını belirler. Değer 0 ise boyutunu değiştirmez, 1 ise diğer 1 olanlarla beraber orantılı yayılır, 2 ise diğerlerine oranla 2 katı yayılır.
flag parametresi ise kontrolün boyutlandırıcı içindeki davranışını daha ileri seviyelerde ayarlarız. Kontroller arasında çizilecek sınırları belirleyebiliriz, kontroller arasında verilecek boşluk belirleyebiliriz. Bir liste dökümanda var. Sınır bilgisi border değerinin hangi kenarlara uygulanacağı da bu flag içinde belirtilir. Flag bitleri birbirine veya işareti | ile bağlanır (ki zaten tamsayı değerler veya ediliyor). Örneğin Wx::LEFT | Wx::BOTTOM ile solda ve altta border değerini uygulayacağımızı belirtiriz.
- Wx::LEFT
- Wx::RIGHT
- Wx::BOTTOM
- Wx::TOP
- Wx::ALL
Panele boyutlandırıcı eklerken set_sizer metodu kullanılır.
border.rb
require "wx"
class Örnek < Wx::Frame
def initialize(*args)
super(*args)
init_UI
end
def init_UI
set_size [350, 300]
set_title "Border"
centre
panel = Wx::Panel.new(self)
panel.background_colour = "#4f5049"
vbox = Wx::BoxSizer.new(Wx::VERTICAL)
midPan = Wx::Panel.new(panel)
midPan.background_colour = "#ededed"
vbox.add midPan, Wx::ID_ANY, Wx::EXPAND | Wx::ALL, 20
panel.set_sizer vbox
end
end
Wx::App.run {
Örnek.new(nil).show
}
Yukarıdaki kodda içteki paneli boyutlandırıcıya eklerken etrafında biraz boşluk bıraktık.
vbox.add midPan, Wx::ID_ANY, Wx::EXPAND | Wx::ALL, 20
midPan panelini (bu arada isimi keşke mid_pan yazsam daha Ruby olurdu), vbox boyutlandırıcısına eklerken 20 piksel sınır belirledik. Sınırın her tarafta olması da flag değerine girilen Wx::ALL biti tarafından belirtiliyor.
Eğer Wx::EXPAND bayrağını kullanırsak widget'imiz boyutlandırıcı içinde yayılabildiği kadar her yöne yayılır. Son olarak widget'imizin yaslanmasını da bayraklar ile belirleyebiliriz.
- Wx::ALIGN_LEFT
- Wx::ALIGN_RIGHT
- Wx::ALIGN_TOP
- Wx::ALIGN_BOTTOM
- Wx::ALIGN_CENTER_VERTICAL
- Wx::ALIGN_CENTER_HORIZONTAL
- Wx::ALIGN_CENTER
Çalıştıralım

Sınıfına git örneği
Önümüzdeki örnekte farklı birçok yöntem göreceğiz.
goto_class.rb
require "wx"
class Örnek < Wx::Frame
def initialize(*args)
super(*args)
init_UI
end
def init_UI
#set_size [350, 300]
set_title "Sınıfına Git"
centre
panel = Wx::Panel.new(self)
font = Wx::SystemSettings.get_font(Wx::SYS_SYSTEM_FONT)
font.point_size = 9
vbox = Wx::BoxSizer.new(Wx::VERTICAL)
hbox1 = Wx::BoxSizer.new(Wx::HORIZONTAL)
st1 = Wx::StaticText.new(panel, label: 'Class Adı :')
st1.font = font
hbox1.add st1, 0, Wx::RIGHT, 8
tc = Wx::TextCtrl.new(panel)
hbox1.add tc, 1
vbox.add hbox1, 0, Wx::EXPAND|Wx::LEFT|Wx::RIGHT|Wx::TOP, 10
vbox.add -1, 10
hbox2 = Wx::BoxSizer.new(Wx::HORIZONTAL)
st2 = Wx::StaticText.new(panel, label: 'Eşleşen Sınıflar :')
st2.set_font font
hbox2.add st2
vbox.add hbox2, 0, Wx::LEFT | Wx::TOP, 10
vbox.add -1, 10
hbox3 = Wx::BoxSizer.new(Wx::HORIZONTAL)
tc2 = Wx::TextCtrl.new(panel, style: Wx::TE_MULTILINE)
hbox3.add tc2, 1, Wx::EXPAND
vbox.add hbox3, 1, Wx::LEFT|Wx::RIGHT|Wx::EXPAND, 10
vbox.add -1, 25
hbox4 = Wx::BoxSizer.new(Wx::HORIZONTAL)
cb1 = Wx::CheckBox.new(panel, label: 'Büyük/Küçük Duyarlı')
cb1.font = font
hbox4.add cb1
cb2 = Wx::CheckBox.new(panel, label: 'İçiçe Sınıflar')
cb2.font = font
hbox4.add cb2, 0, Wx::LEFT, 10
cb3 = Wx::CheckBox.new(panel, label: 'Non-Project Sınıflar')
cb3.font = font
hbox4.add cb3, 0, Wx::LEFT, 10
vbox.add hbox4, 0, Wx::LEFT, 10
vbox.add -1, 25
hbox5 = Wx::BoxSizer.new(Wx::HORIZONTAL)
btn1 = Wx::Button.new(panel, label: 'Tamam', size: [70, 30])
hbox5.add btn1
btn2 = Wx::Button.new(panel, label: 'Kapat', size: [70, 30])
hbox5.add btn2, 0, Wx::LEFT|Wx::BOTTOM, 5
vbox.add hbox5, 0, Wx::ALIGN_RIGHT|Wx::RIGHT, 10
panel.set_sizer vbox
end
end
Wx::App.run {
Örnek.new(nil).show
}
Gördüğünüz üzere yerleşimleri kombinasyon yaptık. Bir dikey boyutlandırıcı, 5 yatay boyutlandırıcı var.
font = Wx::SystemSettings.get_font(Wx::SYS_SYSTEM_FONT)
font.point_size = 9
Sistemden SYS_SYSTEM_FONT yazı tipini alıp boyutunu 9 olarak ayarlayıp kontrollerimizde kullanıyoruz. Wx::SystemFont dökümanında sistemden alınan font isimleri var.
vbox.add hbox1, 0, Wx::EXPAND|Wx::LEFT|Wx::RIGHT|Wx::TOP, 10
vbox.add -1, 10
Boyutlandırıcı içine eleman eklerken kenarlarında istediğimiz boşlukları bayrak bitleri ve border argümanı ile ayarlayabiliyorduk. Yukarıdaki satırda hbox1 eklenirken solu, sağı ve üstünde 10 piksel boşluk veriliyor.
Bir diğer yöntem boyutlandırıcı nesnenin add metodu ile direk olarak eklenen elemanlar arasına boşluk eklemek. Burada vbox.add -1, 10 satırı genişliği -1 yüksekliği 10 piksel bir boşluk ekliyor, yani dikey olarak bir sonra eklenecek elemanla araya 10 piksel boşluk ekliyor.
vbox.add hbox5, 0, Wx::ALIGN_RIGHT|Wx::RIGHT, 10
Bu satır hbox5 içindeki iki butonu yerleşime eklerken sağa yaslayarak yerleştiriyor. Burada 3 konu önemli, orantı bilgisi (proportion), yaslanma biti ve Wx::EXPAND. Proportion sıfır olmalıdır ki butonlar pencereyle beraber büyümeye kalkmasın ne kadarsa o kadar kalsın. Wx::EXPAND kullanmamalıyız, butonlar yalnızca kendilerine ayrılan alanı kaplasın. Son olarak da Wx::ALIGN_RIGHT bayrağını da kullanmalıyız ki butonlar pencerenin sağ tarafına yerleştirilsin.
Çalıştıralım.

Wx::GridSizer
Wx::GridSizer kontrolleri iki boyutlu tablo şeklinde yerleştirir. Tablodaki her hücre eşit boyutlardadır.
Wx:GridSizer.new(rows, cols, vgap, hgap)
Üretici metodda satır sayısı, sütun sayısı, hücreler arası dikeydeki boşluk (satırlar arası) ve hücreler arası yataydaki boşluk değerlerini argüman olarak veriyoruz.
Örneğimizde bir hesap makinesinin görselini hazırlıyoruz.
calculator.rb
require "wx"
class Örnek < Wx::Frame
def initialize(*args)
super(*args)
init_UI
end
def init_UI
set_title "Hesap Makinesi"
centre
menubar = Wx::MenuBar.new
file_menu = Wx::Menu.new
menubar.append file_menu, '&File'
set_menu_bar menubar
vbox = Wx::BoxSizer.new(Wx::VERTICAL)
display = Wx::TextCtrl.new(self, style: Wx::TE_RIGHT)
vbox.add display, 0, Wx::EXPAND|Wx::TOP|Wx::BOTTOM, 4
gs = Wx::GridSizer.new(5, 4, 5, 5)
gs.add Wx::Button.new(self, label: 'Cls'), 0, Wx::EXPAND
gs.add Wx::Button.new(self, label: 'Bck'), 0, Wx::EXPAND
gs.add Wx::StaticText.new, 0, Wx::EXPAND
gs.add Wx::Button.new(self, label: 'Close'), 0, Wx::EXPAND
gs.add Wx::Button.new(self, label: '7'), 0, Wx::EXPAND
gs.add Wx::Button.new(self, label: '8'), 0, Wx::EXPAND
gs.add Wx::Button.new(self, label: '9'), 0, Wx::EXPAND
gs.add Wx::Button.new(self, label: '/'), 0, Wx::EXPAND
gs.add Wx::Button.new(self, label: '4'), 0, Wx::EXPAND
gs.add Wx::Button.new(self, label: '5'), 0, Wx::EXPAND
gs.add Wx::Button.new(self, label: '6'), 0, Wx::EXPAND
gs.add Wx::Button.new(self, label: '*'), 0, Wx::EXPAND
gs.add Wx::Button.new(self, label: '1'), 0, Wx::EXPAND
gs.add Wx::Button.new(self, label: '2'), 0, Wx::EXPAND
gs.add Wx::Button.new(self, label: '3'), 0, Wx::EXPAND
gs.add Wx::Button.new(self, label: '-'), 0, Wx::EXPAND
gs.add Wx::Button.new(self, label: '0'), 0, Wx::EXPAND
gs.add Wx::Button.new(self, label: '.'), 0, Wx::EXPAND
gs.add Wx::Button.new(self, label: '='), 0, Wx::EXPAND
gs.add Wx::Button.new(self, label: '+'), 0, Wx::EXPAND
vbox.add gs, 1, Wx::EXPAND
set_sizer vbox
end
end
Wx::App.run {
Örnek.new(nil).show
}
Bck ve Close butonları arasındaki grid hücresini nasıl boş bıraktığımıza dikkat edin , sadece boş bir Wx::StaticText nesnesi koyduk.
Kontroller grid boyutlandırıcıya eklendikleri sırayla görüntüde yerlerini alıyorlar. Soldan sağa, yukarıdan aşağı yönde ilerleniyor. Satır bittikçe alt satırın başına geçiliyor.

Wx::FlexGridSizer
Bu boyutlandırıcı Wx::GridSizer'a çok benzer. Bu da kontrolleri 2 boyutlu bir tabloda yerleştirir. Ama hücre boyutlarına biraz esneklik getirir. FlexGridSizer'da aynı satırdaki tüm hücreler aynı yüksekliktedir ve aynı sütundaki tüm hücreler de aynı genişliktedir. Ancak satırların yükseklikleri ve sütunların genişlikleri değişebilir.
Wx::FlexGridSizer.new(rows, cols, vgap, hgap)
Yeni nesne üretme metodu aynı argümanları alıyor.
Geliştiriciler sıklıkla verileri göstermek ve değiştirmek amaçlı diyalog pencereleri hazırlarlar. Wx::FlexGridSizer boyutlandırıcı bu diyalogların yerleşimini hazırlarken çok işe yarar.
review.rb
require "wx"
class Örnek < Wx::Frame
def initialize(*args)
super(*args)
init_UI
end
def init_UI
set_size [350, 250]
set_title "Eleştiri"
centre
panel = Wx::Panel.new self
hbox = Wx::BoxSizer.new Wx::HORIZONTAL
fgs = Wx::FlexGridSizer.new 3, 2, 9, 25
başlık = Wx::StaticText.new panel, label: "Başlık :"
yazar = Wx::StaticText.new panel, label: "Yazar :"
eleştiri = Wx::StaticText.new panel, label: "Eleştiri :"
tc1 = Wx::TextCtrl.new panel
tc2 = Wx::TextCtrl.new panel
tc3 = Wx::TextCtrl.new panel, style: Wx::TE_MULTILINE
fgs.add başlık
fgs.add tc1, 1, Wx::EXPAND
fgs.add yazar
fgs.add tc2, 1, Wx::EXPAND
fgs.add eleştiri, 1, Wx::EXPAND
fgs.add tc3, 1, Wx::EXPAND
fgs.add_growable_row 2
fgs.add_growable_col 1
hbox.add fgs, 1, Wx::ALL|Wx::EXPAND, 15
panel.set_sizer hbox
end
end
Wx::App.run {
Örnek.new(nil).show
}
Yukarıdaki örnekte eleştiri giriş diyaloğunu FlexGridSizer ile oluşturduk
hbox = Wx::BoxSizer.new Wx::HORIZONTAL
....
hbox.add fgs, 1, Wx::ALL|Wx::EXPAND, 15
Yatay boyutlandırıcıdan kenarlara 15 piksel boşluk bırakıyoruz.
fgs = Wx::FlexGridSizer.new 3, 2, 9, 25
3 satır , 2 sütundan oluşuyor. Satırlar arasında 9 piksel , sütunlar arasında 25 piksel boşluk var.
fgs.add başlık
....
fgs.add tc3, 1, Wx::EXPAND
Kontrolleri hücrelere aynı GridSizer gibi sırayla ekliyoruz.
fgs.add_growable_row 2
fgs.add_growable_col 1
3. satır (index=2) ve ikinci sütunu genişleyebilir olarak belirtiyoruz. Bunları yapmazsak kontroller birbirine ayak uydurur ama boyutlandırıcı genişlemediği için pencereyle beraber büyümezler. Ayrıca büyümesini istediğimiz kontrolleri boyutlandırıcıya eklerken Wx::EXPAND bayrağını eklemeyi unutmayın.

Wx::GridBagSizer
GridBagSizer Wx kütüphanesinin en esnek boyutlandırıcısı.
Bu boyutlandırıcı elemanların ayrıca pozisyonlanmasına imkan tanır. Elemanlar bir'den fazla satır veya sütuna da yayılabilirler.
Wx::GridBagSizer.new vgap, hgap
Nesne oluşturucusu çok basittir. Argümanlar satırlar arası dikey boşluk ve sütunlar arası yatay boşluk değeri. Kontrolleri boyutlandırıcıya add metodu ile ekleriz.
add window, pos, span = Wx::DEFAULT_SPAN, flag = 0, border = 0, userData = nil
window boyutlandırıcıya eklenecek olan widget, pos satır-sütun olarak pozisyon değeri (Wx::GBPosition nesnesi), span kaç satır , kaç sütun işgal edeceği (Wx::GBSpan nesnesi), bayrafklar ve kenar boşluğu.
İsim değiştir diyalog örneği
İlk örneğimizde isim değiştirmek için bir diyalog penceresi çizelim. Sadece bir Wx::StaticText, bir Wx::TextCtrl ve iki Wx::Button widget var.
rename.rb
require "wx"
class Örnek < Wx::Frame
def initialize(*args)
super(*args)
init_UI
end
def init_UI
set_size [350, 150]
set_title "İsim Değiştir"
centre
panel = Wx::Panel.new self
sizer = Wx::GridBagSizer.new 4, 4
text = Wx::StaticText.new panel, label: "Yeni isim :"
sizer.add text, Wx::GBPosition.new(0, 0), Wx::DEFAULT_SPAN,
Wx::TOP|Wx::LEFT|Wx::BOTTOM, 5
tc = Wx::TextCtrl.new panel
sizer.add tc, Wx::GBPosition.new(1, 0), Wx::GBSpan.new(1, 4),
Wx::EXPAND|Wx::LEFT|Wx::RIGHT, 5
button_ok = Wx::Button.new panel, label: "Tamam", size: [90, 28]
button_close = Wx::Button.new panel, label: "Kapat", size: [90, 28]
sizer.add button_ok, Wx::GBPosition.new(3, 2)
sizer.add button_close, Wx::GBPosition.new(3, 3), Wx::DEFAULT_SPAN,
Wx::RIGHT|Wx::BOTTOM, 10
sizer.add_growable_col 1
sizer.add_growable_row 2
panel.set_sizer sizer
end
end
Wx::App.run {
Örnek.new(nil).show
}
Pencereye büyük bir grid tablosu olarak bakmalıyız.
text = Wx::StaticText.new panel, label: "Yeni isim :"
sizer.add text, Wx::GBPosition.new(0, 0), Wx::DEFAULT_SPAN,
Wx::TOP|Wx::LEFT|Wx::BOTTOM, 5
"Yeni isim :" yazısı sol üst köşeye yerleştiriliyor, pozisyonu (0. 0). Solunda , üstünde ve altında da biraz boşluk bırakıyoruz.
tc = Wx::TextCtrl.new panel
sizer.add tc, Wx::GBPosition.new(1, 0), Wx::GBSpan.new(1, 4),
Wx::EXPAND|Wx::LEFT|Wx::RIGHT, 5
Wx::TextCtrl nesnesi ikinci satırın ilk sütununa yerleştiriliyor (1, 0). Yayılma olarak 1 satır ve 4 sütuna yayılıyor (1, 4). Ve iki yanında 5 piksel boşluk bırakıyoruz.
sizer.add button_ok, Wx::GBPosition.new(3, 2)
sizer.add button_close, Wx::GBPosition.new(3, 3), Wx::DEFAULT_SPAN,
Wx::RIGHT|Wx::BOTTOM, 10
Butonlarımızı 4. satıra yerleştiriyoruz. 3. satırı boş bırakıyoruz TextCtrl ve butonlar arasında mesafe kalsınistiyoruz. "Tamam" butonunu 3. sütuna (3, 2) ve "Kapat" butonunu da 4. sütuna (3, 3) yerleştiriyoruz. Sadece "Kapat" butonuna sınır boşluğu veriliyor ama altında olan boşluk diğer butona da etki edecektir.
sizer.add_growable_col 1
sizer.add_growable_row 2
Son yapacağımız şey , yerleşimin boyut değişimlerine tepkisi. 2. sütun ve 3. satırı genişleyebilir yaptık. Bu iki satırı yoruma atın da ne olacağını görün.

Yeni sınıf diyaloğu örneği
Şimdiki örneğimizde JDeveloper'da bulunan yeni Java sınıf tanımlama diyaloğunu taklit edeceğiz.
require "wx"
class Örnek < Wx::Frame
def initialize(*args)
super(*args)
init_UI
end
def init_UI
set_size [350, 450]
set_title "Create Java Class"
centre
panel = Wx::Panel.new self
sizer = Wx::GridBagSizer.new 8, 5
text1 = Wx::StaticText.new panel, label: "Java Class"
sizer.add text1, Wx::GBPosition.new(0, 0), Wx::DEFAULT_SPAN,
Wx::TOP|Wx::LEFT|Wx::BOTTOM, 15
icon = Wx::StaticBitmap.new panel, label: Wx::Bitmap.new('exec.jpg')
sizer.add icon, Wx::GBPosition.new(0, 4), Wx::DEFAULT_SPAN,
Wx::TOP|Wx::RIGHT|Wx::ALIGN_RIGHT, 5
line = Wx::StaticLine.new panel
sizer.add line, Wx::GBPosition.new(1, 0), Wx::GBSpan.new(1, 5),
Wx::EXPAND|Wx::BOTTOM, 10
text2 = Wx::StaticText.new panel, label: "Name"
sizer.add text2, Wx::GBPosition.new(2, 0), Wx::DEFAULT_SPAN,
Wx::LEFT, 10
tc1 = Wx::TextCtrl.new panel
sizer.add tc1, Wx::GBPosition.new(2, 1), Wx::GBSpan.new(1, 3),
Wx::TOP|Wx::EXPAND
text3 = Wx::StaticText.new panel, label: "Package"
sizer.add text3, Wx::GBPosition.new(3, 0), Wx::DEFAULT_SPAN,
Wx::LEFT|Wx::TOP, 10
tc2 = Wx::TextCtrl.new panel
sizer.add tc2, Wx::GBPosition.new(3, 1), Wx::GBSpan.new(1, 3),
Wx::TOP|Wx::EXPAND, 5
button1 = Wx::Button.new panel, label: "Browse..."
sizer.add button1, Wx::GBPosition.new(3, 4), Wx::DEFAULT_SPAN,
Wx::TOP|Wx::RIGHT, 5
text4 = Wx::StaticText.new panel, label: "Extends"
sizer.add text4, Wx::GBPosition.new(4, 0), Wx::DEFAULT_SPAN,
Wx::TOP|Wx::LEFT, 10
combo = Wx::ComboBox.new panel
sizer.add combo, Wx::GBPosition.new(4, 1), Wx::GBSpan.new(1, 3),
Wx::TOP|Wx::EXPAND, 5
button2 = Wx::Button.new panel, label: "Browse..."
sizer.add button2, Wx::GBPosition.new(4, 4), Wx::DEFAULT_SPAN,
Wx::TOP|Wx::RIGHT, 5
sb = Wx::StaticBox.new panel, label: "Optional Attributes"
boxsizer = Wx::StaticBoxSizer.new sb, Wx::VERTICAL
boxsizer.add Wx::CheckBox.new(panel, label: "Public"), 0,
Wx::LEFT|Wx::TOP, 5
boxsizer.add Wx::CheckBox.new(panel, label: "Generate Default Constructor"), 0,
Wx::LEFT, 5
boxsizer.add Wx::CheckBox.new(panel, label: "Generate Main Method"), 0,
Wx::LEFT|Wx::BOTTOM, 5
sizer.add boxsizer, Wx::GBPosition.new(5, 0), Wx::GBSpan.new(1, 5),
Wx::EXPAND|Wx::TOP|Wx::LEFT|Wx::RIGHT , 10
button3 = Wx::Button.new panel, label: 'Help'
sizer.add button3, Wx::GBPosition.new(7, 0), Wx::DEFAULT_SPAN,
Wx::LEFT, 10
button4 = Wx::Button.new panel, label: "Ok"
sizer.add button4, Wx::GBPosition.new(7, 3)
button5 = Wx::Button.new panel, label: "Cancel"
sizer.add button5, Wx::GBPosition.new(7, 4), Wx::GBSpan.new(1, 1),
Wx::BOTTOM|Wx::RIGHT, 10
sizer.add_growable_col 2
sizer.add_growable_row 6
panel.set_sizer sizer
sizer.fit self
end
end
Wx::App.run {
Örnek.new(nil).show
}
Bu daha karmaşık bir yerleşim , hem GridBoxSizer hem de StaticBoxSizer kullanıyoruz.
line = Wx::StaticLine.new panel
sizer.add line, Wx::GBPosition.new(1, 0), Wx::GBSpan.new(1, 5),
Wx::EXPAND|Wx::BOTTOM, 10
Bu yerleşimde iki grup elemanı birbirinden ayıran çizgi. 2. satıra yatay olarak tüm satırı kaplayacak şekilde yerleştiriyoruz.
icon = Wx::StaticBitmap.new panel, label: Wx::Bitmap.new('exec.jpg')
sizer.add icon, Wx::GBPosition.new(0, 4), Wx::DEFAULT_SPAN,
Wx::TOP|Wx::RIGHT|Wx::ALIGN_RIGHT, 5
İlk satıra sağa yanaşmış olarak bir resimi StaticBitmap nesnesi olarak ekliyoruz.
sb = Wx::StaticBox.new panel, label: "Optional Attributes"
boxsizer = Wx::StaticBoxSizer.new sb, Wx::VERTICAL
StaticBox üzerinde bir etiket yazısı olan panel gibi düşünülebilir. Burada bir şey dikkatimi çekti , sb içine boxsizer'ı ekliyoruz ama daha sonra yerleşime kapsayıcı olan sb'yi değil bozsizer'ı ekliyoruz. Biraz araştırdım, aslında birinci satıra gerek olamadan sadece
boxsizer = Wx::StaticBoxSizer.new Wx::VERTICAL, panel, "Optional Attributes"
şeklinde yazarak boxsizer nesnesine zaten başlık ekleyebiliyoruz. Bu daha mantıklı ve kısa.

Çalıştı ama şu GridBagSizer#add metodunun argümanlarında bulunan Wx::GBPosition ve Wx::GBSpan nesnesi üretmelerine gıcık oldum, her seferinde bunları yazmak çok gıcık, araştırdım bir kısaltmasını da bulamadım. Oturdum kendime bir yardımcı kod dosyası hazırladım.
my_wx_helper.rb
class Wx::GridBagSizer
wx_add = instance_method :add
wx_redefine_method :add do |*args|
if args[1].class == Array && args[1].length == 2
args[1] = Wx::GBPosition.new args[1][0], args[1][1]
end
if args[2].class == Array && args[2].length == 2
args[2] = Wx::GBSpan.new args[2][0], args[2][1]
end
wx_add.bind(self).call(*args)
end
end
Bu kodu programlarıma dahil edersem pos ve span değerlerini array içinde verebiliriz. Kodumu bu yardımcı dosyamı kullanacak şekilde değiştirince birazcık sadeleşti.
require "wx"
require "./my_wx_helper"
class Örnek < Wx::Frame
def initialize(*args)
super(*args)
init_UI
end
def init_UI
set_size [350, 450]
set_title "Create Java Class"
centre
panel = Wx::Panel.new self
sizer = Wx::GridBagSizer.new 8, 5
text1 = Wx::StaticText.new panel, label: "Java Class"
sizer.add text1, [0, 0], [1, 1],
Wx::TOP|Wx::LEFT|Wx::BOTTOM, 15
icon = Wx::StaticBitmap.new panel, label: Wx::Bitmap.new('exec.jpg')
sizer.add icon, [0, 4], [1, 1],
Wx::TOP|Wx::RIGHT|Wx::ALIGN_RIGHT, 5
line = Wx::StaticLine.new panel
sizer.add line, [1, 0], [1, 5], Wx::EXPAND|Wx::BOTTOM, 10
text2 = Wx::StaticText.new panel, label: "Name"
sizer.add text2, [2, 0], [1, 1], Wx::LEFT, 10
tc1 = Wx::TextCtrl.new panel
sizer.add tc1, [2, 1], [1, 3], Wx::TOP|Wx::EXPAND
text3 = Wx::StaticText.new panel, label: "Package"
sizer.add text3, [3, 0], [1, 1], Wx::LEFT|Wx::TOP, 10
tc2 = Wx::TextCtrl.new panel
sizer.add tc2, [3, 1], [1, 3], Wx::TOP|Wx::EXPAND, 5
button1 = Wx::Button.new panel, label: "Browse..."
sizer.add button1, [3, 4], [1, 1], Wx::TOP|Wx::RIGHT, 5
text4 = Wx::StaticText.new panel, label: "Extends"
sizer.add text4, [4, 0], [1, 1], Wx::TOP|Wx::LEFT, 10
combo = Wx::ComboBox.new panel
sizer.add combo, [4, 1], [1, 3], Wx::TOP|Wx::EXPAND, 5
button2 = Wx::Button.new panel, label: "Browse..."
sizer.add button2, [4, 4], [1, 1], Wx::TOP|Wx::RIGHT, 5
boxsizer = Wx::StaticBoxSizer.new Wx::VERTICAL, panel, "Optional Attributes"
boxsizer.add Wx::CheckBox.new(panel, label: "Public"), 0,
Wx::LEFT|Wx::TOP, 5
boxsizer.add Wx::CheckBox.new(panel, label: "Generate Default Constructor"), 0,
Wx::LEFT, 5
boxsizer.add Wx::CheckBox.new(panel, label: "Generate Main Method"), 0,
Wx::LEFT|Wx::BOTTOM, 5
sizer.add boxsizer, [5, 0], [1, 5],
Wx::EXPAND|Wx::TOP|Wx::LEFT|Wx::RIGHT , 10
button3 = Wx::Button.new panel, label: 'Help'
sizer.add button3, [7, 0], [1, 1], Wx::LEFT, 10
button4 = Wx::Button.new panel, label: "Ok"
sizer.add button4, [7, 3]
button5 = Wx::Button.new panel, label: "Cancel"
sizer.add button5, [7, 4], [1, 1], Wx::BOTTOM|Wx::RIGHT, 10
sizer.add_growable_col 2
sizer.add_growable_row 6
panel.set_sizer sizer
sizer.fit self
end
end
Wx::App.run {
Örnek.new(nil).show
}
Yerleşimler üzerine yazacaklarım bu kadar, sonraki sayfada olay işlemelere gireceğiz inşallah.
Şimdilik kalın sağlıcakla..
Hiç yorum yok:
Yorum Gönder