https://ujk-ujk.blogspot.com/2025/03/wxruby3-ile-masaustu-uygulama_12.html
        
 Selam WxRuby3 GUI kütüphanesi denemelerimize widget'ları inceleyerek devam ediyoruz.
Wx::ToggleButton
Wx::ToogleButton iki pozisyonu olan bir buton nesnesi: basılı ve basılı olmayan görünümleri var. Her tıkladığımızda bu iki durum arasında değişiyor. Bazen bu şekil çalışan butonlar lazım olur. 
Wx::ToggleBuuton.new metodunun parametreleri.
initialize(parent, id, label, pos = Wx::DEFAULT_POSITION, 
  size = Wx::DEFAULT_SIZE, style = 0, val = Wx::DEFAULT_VALIDATOR, 
  name = Wx::CHECK_BOX_NAME_STR)
parent, id ve label sıralı verilmek zorunda onları verdikten sonra diğerlerini sırası olmadan key parametre olarak verebiliriz.
toggle_buttons.rb
require "wx"
class Örnek < Wx::Frame
  def initialize(*args)
    super(*args)
    init_UI
  end
  def init_UI
    set_size [350, 250]
    set_title "Wx::ToogleButton"
    centre
    pnl = Wx::Panel.new self
    @col = Wx::Colour.new 0, 0, 0 
    rtb = Wx::ToggleButton.new pnl, Wx::ID_ANY, 'kırmızı', [20, 25]
    gtb = Wx::ToggleButton.new pnl, Wx::ID_ANY, 'yeşil', [20, 60]
    btb = Wx::ToggleButton.new pnl, Wx::ID_ANY, 'mavi', [20, 100]
    @cpnl  = Wx::Panel.new pnl, pos: [150, 20], size: [110, 110]
    @cpnl.background_colour = @col
    evt_togglebutton rtb, :toggle_red 
    evt_togglebutton gtb, :toggle_green
    evt_togglebutton btb, :toggle_blue
  end
  def toggle_red(e)
    obj = e.get_event_object
    is_pressed = obj.get_value
    green = @col.green
    blue = @col.blue
    if is_pressed
      @col.set 255, green, blue
    else
      @col.set 0, green, blue
    end
    @cpnl.background_colour = @col
    @cpnl.refresh
  end
  def toggle_green(e)
    obj = e.get_event_object
    is_pressed = obj.get_value
    red = @col.red
    blue = @col.blue
    if is_pressed
      @col.set red, 255, blue
    else
      @col.set red, 0, blue
    end
    @cpnl.background_colour = @col
    @cpnl.refresh
  end
  def toggle_blue(e)
    obj = e.get_event_object
    is_pressed = obj.get_value
    red = @col.red
    green = @col.green
    if is_pressed
      @col.set red, green, 255
    else
      @col.set red, green, 0
    end
    @cpnl.background_colour = @col
    @cpnl.refresh
  end
end
Wx::App.run {
  Örnek.new(nil).show
}
Bu colour ve centre kelimeleri gerçekten canımı sıkıyor, niye center değil niye color değil de daha az kullanılan kelimeleri tercih etmişler. 
Bu uygulamada bir panel üzerinde kırmızı yeşil ve mavi seçebileceğimiz 3 toggle buton koyduk. 
    rtb = Wx::ToggleButton.new pnl, Wx::ID_ANY, 'kırmızı', [20, 25]
Üzerinde kırmızı yazan butonu oluşturuyor. Argümanlar sıralı verildiği için key parametre ihtiyacımız yok. 
    @cpnl  = Wx::Panel.new pnl, pos: [150, 20], size: [110, 110]
    @cpnl.background_colour = @col
Bu panelin rengini bizim butonlarımız değiştirecek.
    evt_togglebutton rtb, :toggle_red 
    evt_togglebutton gtb, :toggle_green
    evt_togglebutton btb, :toggle_blue
Olay işleme metodları, evt_togglebutton ve ilk argümanda buton ya da butonun ID değeri, ikinci argümanda ise çağrılacak metod adı sembol olarak verilir. Metod çağırmayıp direk orada kod bloğu koyacaksak argümanlar tabi ki parantez içinde verilmeli.
    evt_togglebutton(rtb) { p "bişey" }
gibi.
  def toggle_red(e)
    obj = e.get_event_object
    is_pressed = obj.get_value
    green = @col.green
    blue = @col.blue
    if is_pressed
      @col.set 255, green, blue
    else
      @col.set 0, green, blue
    end
    @cpnl.background_colour = @col
    @cpnl.refresh
  end
Önce olaya sebep olan butonun basılı olmasını test edip is_pressed değişkenine kaydediyoruz. Daha sonra panelin mevcut olan yeşil ve mavi renk değerlerini alıp üzerine kırmızı yazılı butonumuzun basılı olup olmamasına göre rengin kırmızı bileşenini veriyoruz. Son olarak gösterge panelimizin rengini bulduğumuz değere eşitleyip, panelin refresh metodunu çağırarak tekrar boyanmasını sağlıyoruz.

Wx::StaticText
Wx::StaticText nesnesi birçok diğer GUI kütüphanelerinde label adıyla geçen sabit yazı nesnesi, genelde kullanıcının değiştirmeyeceği yazıları bir yerlere yazdırırken kullanırız. 
initialize(parent, id, label, pos = Wx::DEFAULT_POSITION, 
  size = Wx::DEFAULT_SIZE, style = 0, 
  name = Wx::STATIC_TEXT_NAME_STR)
Bütün temel kontrollerin new metodu benziyor, parent, id, label değerleri sıralı verilmek zorunda diğerleri key parametre olarak verilebilir.
static_text.rb
require "wx"
class Örnek < Wx::Frame
  def initialize(*args)
    super(*args)
    init_UI
  end
  def init_UI
    #set_size [350, 250]
    set_title "Orhan Veli Kanık"
    centre
    txt1 = "Eskiler alıyorum 
Alıp yıldız yapıyorum 
Musiki ruhun gıdasıdır 
Musikiye bayılıyorum"
    txt2 = "Şiir yazıyorum 
Şiir yazıp eskiler alıyorum 
Eskiler verip musikiler alıyorum
Bir de rakı şişesinde balık olsam"
    pnl = Wx::Panel.new self
    vbox = Wx::BoxSizer.new Wx::VERTICAL
    font = Wx::Font.new 13, Wx::FONTFAMILY_DEFAULT, 
      Wx::FONTSTYLE_NORMAL, Wx::FONTWEIGHT_NORMAL
    st1 = Wx::StaticText.new pnl, Wx::ID_ANY, txt1, style: Wx::ALIGN_LEFT
    st2 = Wx::StaticText.new pnl, Wx::ID_ANY, txt2, style: Wx::ALIGN_LEFT
    st1.font = font
    st2.font = font
    vbox.add st1, 0, Wx::ALL, 15
    vbox.add st2, 0, Wx::ALL, 15
        
    pnl.set_sizer vbox 
  end
end
Wx::App.run {
  Örnek.new(nil).show
}
Ünlü şairimizin çok değerli sözleri.
    font = Wx::Font.new 13, Wx::FONTFAMILY_DEFAULT, 
      Wx::FONTSTYLE_NORMAL, Wx::FONTWEIGHT_NORMAL
StaticText nesnelerimizin yazı fontu için kullanacağımız font değerini oluşturuyoruz. 
    st1 = Wx::StaticText.new pnl, Wx::ID_ANY, txt1, style: Wx::ALIGN_LEFT
    st2 = Wx::StaticText.new pnl, Wx::ID_ANY, txt2, style: Wx::ALIGN_LEFT
Şiirimizin iki kıtasını iki StaticText nesnesinde sola hizalanmış olarak yazıyoruz. 
    st1.font = font
    st2.font = font
Yazı fontumuzu , daha önce oluşturduğumuz font yapıyoruz.
    vbox.add st1, 0, Wx::ALL, 15
    vbox.add st2, 0, Wx::ALL, 15
StaticText nesnelerimizi boyutlandırıcıya etraflarında 15 piksel boşluk olacak şekilde ekliyoruz.

Wx::StaticLine
Bu zımbırtı pencerede yatay ya da dikey bir çizgi gösterir. Genelde kontrol gruplarını ayırmak için kullanılır.
initialize(parent, id = Wx::StandardID::ID_ANY, pos = Wx::DEFAULT_POSITION, 
  size = Wx::DEFAULT_SIZE, style = Wx::LI_HORIZONTAL, 
  name = Wx::STATIC_LINE_NAME_STR)
Sadece parent değeri ile oluştursak default olarak yatay bir çizgi olur. 
static_line.rb
require "wx"
class Örnek < Wx::Frame
  def initialize(*args)
    super(*args)
    init_UI
  end
  def init_UI
    set_size [360, 380]
    set_title "Wx::StaticLine"
    centre
    pnl = Wx::Panel.new self
    font = Wx::Font.new 10, Wx::FONTFAMILY_DEFAULT, 
        Wx::FONTSTYLE_NORMAL, Wx::FONTWEIGHT_BOLD
    heading = Wx::StaticText.new pnl, label: 'Orta Avrupa',
        pos: [25, 15], size: [200, -1]
    heading.font = font
    Wx::StaticLine.new pnl, pos: [25, 50], size: [300,1]
    Wx::StaticText.new pnl, label: 'Slovakya', pos: [25, 80]
    Wx::StaticText.new pnl, label: 'Macaristan', pos: [25, 100]
    Wx::StaticText.new pnl, label: 'Polonya', pos: [25, 120]
    Wx::StaticText.new pnl, label: 'Çek Cumhurüyeti', pos: [25, 140]
    Wx::StaticText.new pnl, label: 'Almanya', pos: [25, 160]
    Wx::StaticText.new pnl, label: 'Slovenya', pos: [25, 180]
    Wx::StaticText.new pnl, label: 'Avusturya', pos: [25, 200]
    Wx::StaticText.new pnl, label: 'İsviçre', pos: [25, 220]
    Wx::StaticText.new pnl, label: '5 445 000', pos: [250, 80]
    Wx::StaticText.new pnl, label: '10 014 000', pos: [250, 100]
    Wx::StaticText.new pnl, label: '38 186 000', pos: [250, 120]
    Wx::StaticText.new pnl, label: '10 562 000', pos: [250, 140]
    Wx::StaticText.new pnl, label: '81 799 000', pos: [250, 160]
    Wx::StaticText.new pnl, label: '2 050 000', pos: [250, 180]
    Wx::StaticText.new pnl, label: '8 414 000', pos: [250, 200]
    Wx::StaticText.new pnl, label: '7 866 000', pos: [250, 220]
    Wx::StaticLine.new pnl, pos: [25, 260], size: [300,1]
    tsum = Wx::StaticText.new pnl, label: '164 336 000', pos: [240, 280]
    sum_font = tsum.get_font
    sum_font.weight = Wx::FONTWEIGHT_BOLD
    tsum.font = sum_font
    btn = Wx::Button.new pnl, label: 'Kapat', pos: [140, 310]
    evt_button(btn) { close } 
  end
end
Wx::App.run {
  Örnek.new(nil).show
}
Betiğimiz orta Avrupa ülkeleri ve nüfuslarını gösteriyor. Wx::StaticLine ile görseli yakışıklı yapıyoruz.
    Wx::StaticLine.new pnl, pos: [25, 260], size: [300,1]
300 piksel uzunluğundaki bir çizgiyi yatay olarak yerleştiriyor.

Wx::StaticBox
Bu bir çeşit dekoratör eleman. Değişik elemanları bir grupta toplamak için kullanılır. Bu widget grupladığı widget'lardan önce tanımlanmalıdır, ve o widget'lar StaticBox nesnesinin çocuklarıdır (Wx 2.9.1 öncesi kardeşleri idiler ama şimdi çocukları).
initialize(parent, id, label, pos = Wx::DEFAULT_POSITION, 
    size = Wx::DEFAULT_SIZE, style = 0, 
    name = Wx::STATIC_BOX_NAME_STR)
Burada label olarak string değer olabileceği gibi, Wx::Window sınıfından üretilmiş bir alt sınıfın nesnesi de olabilir.
static_box.rb
require "wx"
class Örnek < Wx::Frame
  def initialize(*args)
    super(*args)
    init_UI
  end
  def init_UI
    set_size [270, 250]
    set_title "Wx::StaticBox"
    centre
    pnl = Wx::Panel.new self
    sb = Wx::StaticBox.new pnl, label: 'Kişi Bilgisi', pos: [5, 5], size: [240, 170]
    Wx::CheckBox.new sb, label: 'Erkek', pos: [15, 30]
    Wx::CheckBox.new sb, label: 'Evli', pos: [15, 55]
    Wx::StaticText.new sb, label: 'Yaşı', pos: [15, 95]
    Wx::SpinCtrl.new sb, value: '1', pos: [55, 90], size: [60, -1], min: 1, max: 120
    btn = Wx::Button.new pnl, label: 'Tamam', pos: [90, 185], size: [60, -1]
    evt_button(btn) { close } 
  end
end
Wx::App.run {
  Örnek.new(nil).show
}
4 widget'ı saran bir StaticBox kullandık.

Wx::ComboBox
ComboBox bir yazı edit elemanı ve bir liste kutusunun birleşiminden oluşan bir elemandır. Yazı kutusunun yanında bir aşağı ok işareti olur, ona tıklayınca seçenekleri gösteren bir liste açılır. 
initialize(parent, id, value, pos, size, choices, style = 0, 
  validator = Wx::DEFAULT_VALIDATOR, name = Wx::COMBO_BOX_NAME_STR)
value içinde o anda yazan değer oluyor. Sadece okunabilir olan elemanlar için ya boş string olmalı ya da seçenek listesinden biri olmalıdır. choices seçeneklerin listesini içeren bir string array. 
combo_box.rb
require "wx"
class Örnek < Wx::Frame
  def initialize(*args)
    super(*args)
    init_UI
  end
  def init_UI
    set_size [350, 250]
    set_title "Wx::ComboBox"
    centre
    pnl = Wx::Panel.new self
    distros = ['Ubuntu', 'Arch', 'Fedora', 'Debian', 'Mint']
    cb = Wx::ComboBox.new pnl, pos: [50, 30], choices: distros, 
            style: Wx::CB_READONLY
    st = Wx::StaticText.new pnl, label: '', pos: [50, 140]
    evt_combobox(cb) { st.label = cb.value }
  end
end
Wx::App.run {
  Örnek.new(nil).show
}
ComboBox'ta seçilen seçenek StaticText üzerinde gösterilecek.
    distros = ['Ubuntu', 'Arch', 'Fedora', 'Debian', 'Mint']
Listedeki seçenekleri bir string array içinde topladık.
    cb = Wx::ComboBox.new pnl, pos: [50, 30], choices: distros, 
            style: Wx::CB_READONLY
Wx::CB_READONLY stil bilgisi kutudaki yazının sadece okunabilir olduğunu belirtir. 
    evt_combobox(cb) { st.label = cb.value }
evt_combobox olay işleme metodu listeden bir şey seçince tetiklenir. Önceden seçilmiş olanın aynısını da seçseniz tetiklenir. Sadece combobox okuna ya da combobox dışında bir yere tıklayarak olayı tetiklenmeden çıkabilirsiniz.
value metodu ile ComboBox seçili değeri okuyup StaticText label'ine yazıyoruz.

Wx::CheckBox
CheckBox iki durumu olan bir nesnedir, on ve off. Bir kutu ve yanında bir etiket yazısından oluşur. Etiket kutunun sağında veya solunda olabilir. Eğer CheckBox on durumundaysa kutusunda bit tik işareti olur. Eğer CHK_3STATE stili seçiliyse üçüncü bir durumu olur, bu da genelde seçimin etkisiz olmasını ifade eden anlamlar için kullanılır. 
initialize(parent, id, label, pos = Wx::DEFAULT_POSITION, 
  size = Wx::DEFAULT_SIZE, style = 0, validator = Wx::DEFAULT_VALIDATOR, 
  name = Wx::CHECK_BOX_NAME_STR)
Olası style değerleri
- CHK_2STATE : 2 durumlu CheckBox, default budur
 - CHK_3STATE : 3 durumlu CheckBox
 - CHK_ALLOW_3RD_STATE_FOR_USER : Normalde 3 durumlu kullanırken kullanıcı tıklayarak 3. duruma geçiremez, sadece kodla geçirilir. Ama bu stil seçilirse kullanıcı da tıklayarak 3. duruma geçirebilir.
 - Alignment::ALIGN_RIGHT : Etiket yazısı kutunun solunda çıkar, yani kutu sağa hizalanır
 
check_box.rb
require "wx"
class Örnek < Wx::Frame
  def initialize(*args)
    super(*args)
    init_UI
  end
  def init_UI
    set_size [350, 250]
    set_title "Wx::CheckBox"
    centre
    pnl = Wx::Panel.new self
    vbox = Wx::BoxSizer.new Wx::VERTICAL
    cb = Wx::CheckBox.new pnl, label: 'Title Göster'
    cb.value = true
    evt_checkbox cb, :show_or_hide_title
    vbox.add cb, 0, Wx::TOP|Wx::LEFT, 30
    cb2 = Wx::CheckBox.new pnl, label: 'Kutu sağda', 
      style: Wx::ALIGN_RIGHT 
    vbox.add cb2, 0, Wx::TOP|Wx::LEFT, 30
    hbox = Wx::BoxSizer.new Wx::HORIZONTAL
    @cb3 = Wx::CheckBox.new pnl, label: '3 durumlu', 
      style: Wx::ALIGN_RIGHT | Wx::CHK_3STATE 
    hbox.add @cb3, 0
    @btn1 = Wx::ToggleButton.new pnl, label: "3. durum seç"
    hbox.add @btn1, 0, Wx::LEFT | Wx::RIGHT, 5
    evt_togglebutton(@btn1) { @btn1.value ? 
        @cb3.set3state_value(Wx::CHK_UNDETERMINED) :  
        @cb3.set3state_value(Wx::CHK_UNCHECKED) }
    @btn2 = Wx::ToggleButton.new pnl, label: "3. durum serbest"
    hbox.add @btn2, 0
    evt_togglebutton(@btn2) { @btn2.value ? 
      @cb3.set_window_style(Wx::ALIGN_RIGHT | Wx::CHK_3STATE | 
        Wx::CHK_ALLOW_3RD_STATE_FOR_USER) :  
      @cb3.set_window_style(Wx::ALIGN_RIGHT | Wx::CHK_3STATE) }
    vbox.add hbox, 0, Wx::TOP|Wx::LEFT, 30
    pnl.sizer = vbox
  end
  def show_or_hide_title(e)
    sender = e.get_event_object
    is_checked = sender.value
    if is_checked
      set_title 'Wx::CheckBox'
    else
      set_title ''
    end
  end
end
Wx::App.run {
  Örnek.new(nil).show
}
Bir normal CheckBox, bir kutusu sağda CheckBox ve 3 durumlu bir CheckBox var. 
    cb = Wx::CheckBox.new pnl, label: 'Title Göster'
    cb.value = true
Normal CheckBox tanımı ve başlangıçta tiklenmiş gelmesi. 
    evt_togglebutton(@btn1) { @btn1.value ? 
      @cb3.set3state_value(Wx::CHK_UNDETERMINED) :  
      @cb3.set3state_value(Wx::CHK_UNCHECKED) }
Burada önemli bir şey görülüyor. Normal 2 durumlu CheckBox durumu get_value ve set_value (ya da value = ) metodları ile işlenirken, 3 durumlu CheckBox durumları get3state_value ve set3state_value metodları ile işlenir. 3 durumun değerleri ise Wx::CHK_UNCHECKED, Wx::CHK_CHECKED ve Wx::CHK_UNDETERMINED - 2 durum olunca sadece true ya da false değer olur. 
    evt_togglebutton(@btn2) { @btn2.value ? 
      @cb3.set_window_style(Wx::ALIGN_RIGHT | Wx::CHK_3STATE | 
        Wx::CHK_ALLOW_3RD_STATE_FOR_USER) :  
      @cb3.set_window_style(Wx::ALIGN_RIGHT | Wx::CHK_3STATE) }
Wx::CHK_ALLOW_3RD_STATE_FOR_USER stilini ekleyerek kullanıcıya 3. duruma geçirme izni veriliyor, ilk tıklayışta seçili, ikincide tanımsız, üçüncü tıklayışta seçili değil olur. 

Wx::StatusBar
StatusBar (durum çubuğu) elemanı pencerelerin altında bulunan ve kullanıcıyı bilgilendirmek için kullanılan şeride denir. Farklı bilgileri göstermek için bölümlere ayrılabilir. Durum çubuğu içine başka widget'lar da konabilir. Diyaloglarla kullanıcıyı fazla sıkmamak için küçük bilgiler burada verilebilir. Wx::StatusBar iki yöntemle oluşturulabilir: ya kendi StatusBar nesnemizi oluşturup set_status_bar metodu çağırırız, ya da direk create_status_bar metodunu çağırırız. İkinci yöntem bizim için default bir Wx::StatusBar nesnesi oluşturur.
status_bar.rb
require "wx"
class Örnek < Wx::Frame
  def initialize(*args)
    super(*args)
    init_UI
  end
  def init_UI
    set_size [250, 230]
    set_title "Wx::StatusBar"
    centre
    pnl = Wx::Panel.new self
    button = Wx::Button.new pnl, label: 'Button', pos: [20, 20]
    text = Wx::CheckBox.new pnl, label: 'CheckBox', pos: [20, 90]
    combo = Wx::ComboBox.new pnl, pos: [120, 22], choices: ['Python', 'Ruby']
    slider = Wx::Slider.new pnl, 5, 6, 1, 10, [120, 90], [110, -1]        
    pnl.evt_enter_window { |e| on_widget_enter e }
    button.evt_enter_window { |e| on_widget_enter e }
    text.evt_enter_window { |e| on_widget_enter e }
    combo.evt_enter_window { |e| on_widget_enter e }
    slider.evt_enter_window { |e| on_widget_enter e }
    @sb = create_status_bar
  end
  def on_widget_enter(e)
    isim = e.get_event_object.class.to_s
    @sb.status_text = isim + ' widget'
    e.skip  
  end
end
Wx::App.run {
  Örnek.new(nil).show
}
evt_enter_window ya da buna benzer parametresinde uygulanacağı nesne olmayan olay işleme metodlarda, slider.evt_enter_window şeklinde nesne üzerinde metod çağrılınca sadece blok argüman alıyor. Aslında verdiğimiz metod adını slider nesnesinde arayıp bulamıyor. Bu yüzden blok içinden olay işleyici metoda gönderdik.
    pnl.evt_enter_window { |e| on_widget_enter e }
evt_enter_window olayı widget üzerine mouse girince tetikleniyor. 
  def on_widget_enter(e)
    isim = e.get_event_object.class.to_s
    @sb.status_text = isim + ' widget'
    e.skip  
  end
Önce hangi nesneden olay tetiklendiyse onun sınıf adını alıyoruz. Sonra bu adı durum çubuğuna status_text= metodu ile yazdırıyoruz. set_status_text metodunu da standart Wx metodu olarak kullanabilirdik, ama WxRuby bize kolaylık sağlamış , başka diller gibi set/get uğraşmayalım. Hatta yukarıdaki get_event_object yerine de bunu kullanabiliriz.
  def on_widget_enter(e)
    isim = e.event_object.class.to_s
    @sb.status_text = isim + ' widget'
    e.skip  
  end

Wx::RadioButton
RadioButton kullanıcının bir grup seçenek arasından sadece bir tanesini seçmesini sağlayan widget'dır. Grup belirlemek için grubun ilk RadioButton nesnesine Wx::RB_GROUP stili verilir. Ondan sonra tanımlanan RadioButton nesneleri bu ilk nesne ile aynı grupta kabul edilir. Yeni bir grup başlatmak için, yeni grubun da ilk RadioButton nesnesine Wx::RB_GROUP stili verilir.
radio_button.rb
require "wx"
class Örnek < Wx::Frame
  def initialize(*args)
    super(*args)
    init_UI
  end
  def init_UI
    set_size [210, 210]
    set_title "Wx::RadioButton"
    centre
    pnl = Wx::Panel.new self
    @rb1 = Wx::RadioButton.new pnl, label: 'Değer A', pos: [10, 10], 
            style: Wx::RB_GROUP
    @rb2 = Wx::RadioButton.new pnl, label: 'Değer B', pos: [10, 30]
    @rb3 = Wx::RadioButton.new pnl, label: 'Değer C', pos: [10, 50]
        
    evt_radiobutton @rb1, :set_val   
    evt_radiobutton @rb2, :set_val   
    evt_radiobutton @rb3, :set_val   
    @sb = create_status_bar 3
        
    @sb.set_status_text "true", 0
    @sb.set_status_text "false", 1
    @sb.set_status_text "false", 2
  end
  def set_val(e)
    durum1 = @rb1.value.to_s
    durum2 = @rb2.value.to_s
    durum3 = @rb3.value.to_s
    @sb.set_status_text durum1, 0 
    @sb.set_status_text durum2, 1
    @sb.set_status_text durum3, 2      
  end
end
Wx::App.run {
  Örnek.new(nil).show
}
3 tane RadioButton nesnemiz var.
    @rb1 = Wx::RadioButton.new pnl, label: 'Değer A', pos: [10, 10], 
            style: Wx::RB_GROUP
    @rb2 = Wx::RadioButton.new pnl, label: 'Değer B', pos: [10, 30]
    @rb3 = Wx::RadioButton.new pnl, label: 'Değer C', pos: [10, 50]
İlkinin stiline Wx::RB_GROUP değeri verdik. Daha sonra gelenler aynı grubta kabul edilir. 
    evt_radiobutton @rb1, :set_val   
@rb1 seçilince set_val metodu çağrılıyor.
    @sb = create_status_bar 3
        
    @sb.set_status_text "true", 0
3 bölmeli bir StatusBar tanımlıyoruz. set_status_text  metodu ilk argümanda yazılacak yazıyı, ikinci argümanda hangi bölmeye yazılacağını alıyor. 
    durum1 = @rb1.value.to_s
RadioButton değeri true ya da false olacaktır. 

Wx::Gauge
Wx::Gauge uzun süren işlemlerimizde kullanıcıyı işlemin ne kadarının gerçekleştiği konusunda bilgilendirmek için kullandığımız bir widget. 
gauge_wid.rb
require "wx"
GÖREV_ORANI = 50
class Örnek < Wx::Frame
  def initialize(*args)
    super(*args)
    init_UI
  end
  def init_UI
    set_size [350, 210]
    set_title "Wx::Gauge"
    centre
    @timer = Wx::Timer.new self
    @count = 0
    evt_timer @timer, :on_timer
    pnl = Wx::Panel.new self
    vbox = Wx::BoxSizer.new Wx::VERTICAL
    hbox1 = Wx::BoxSizer.new Wx::HORIZONTAL
    hbox2 = Wx::BoxSizer.new Wx::HORIZONTAL
    hbox3 = Wx::BoxSizer.new Wx::HORIZONTAL
    @gauge = Wx::Gauge.new pnl, range: GÖREV_ORANI, size: [250, -1]
    btn1 = Wx::Button.new pnl, Wx::ID_OK
    btn2 = Wx::Button.new pnl, Wx::ID_STOP
    @text = Wx::StaticText.new pnl, label: 'Görev Başlayacak'
    evt_button btn1, :on_ok
    evt_button btn2, :on_stop
    hbox1.add @gauge, Wx::ALIGN_CENTRE
    hbox2.add btn1, Wx::RIGHT, 10
    hbox2.add btn2
    hbox3.add @text
    vbox.add 0, 30  # boşluk ekleme
    vbox.add hbox1, 1, Wx::ALIGN_CENTRE
    vbox.add 0, 20
    vbox.add hbox2, 1, Wx::ALIGN_CENTRE
    vbox.add hbox3, 1, Wx::ALIGN_CENTRE
    pnl.sizer = vbox
  end
  def on_ok(e)
    if @count >= GÖREV_ORANI
      return
    end
    @timer.start 100
    @text.label = 'Görev Çalışıyor'  
  end
  def on_stop(e)
    if @count == 0 or @count >= GÖREV_ORANI or not @timer.is_running
      return
    end
    @timer.stop
    @text.label = 'Görev Durduruldu'
  end
  def on_timer(e)
    @count += 1
    @gauge.value = @count
    if @count == GÖREV_ORANI
      @timer.stop
      @text.label = 'Görev Tamamlandı'
    end
  end
end
Wx::App.run {
  Örnek.new(nil).show
}
Bir tane Gauge ve iki butonumuz var. Bir buton görevi başlatıyor, diğer, olduğu yerde durduruyor.
    @timer = Wx::Timer.new self
    @count = 0
Görev ilerliyormuş gibi göstermek için bir timer yardımıyla @count değerini zamanla arttıracağız. @count değişkenindeki değer sanki görevin o kadarı gerçekleşmiş gibi Gauge'de gösterilecek. 
    @gauge = Wx::Gauge.new pnl, range: GÖREV_ORANI, size: [250, -1]
Wx::Gauge nesnesi oluşturma kodu, range key parametresi hangi değerde %100 görüneceğini belirler.
  def on_ok(e)
    if @count >= GÖREV_ORANI
      return
    end
    @timer.start 100
    @text.label = 'Görev Çalışıyor'  
  end
OK butonuna tıklanınca eğer sayaç hala maksimum değerimize gelmediyse zamanlayıcıyı 100ms aralıkla çalıştırıyoruz, ve yazıya da görevin çalışıyor olduğunu yazdırıyoruz.
  def on_stop(e)
    if @count == 0 or @count >= GÖREV_ORANI or not @timer.is_running
      return
    end
    @timer.stop
    @text.label = 'Görev Durduruldu'
  end
Stop butonu tıklanınca eğer görev devam ediyorsa zamanlayıcı çalışmasını durdurup sayacın olduğu değerde kalmasını sağlıyoruz. 
  def on_timer(e)
    @count += 1
    @gauge.value = @count
    if @count == GÖREV_ORANI
      @timer.stop
      @text.label = 'Görev Tamamlandı'
    end
  end
Zamanlayıcı çalıştığı müddetçe on_timer olay işleme metodu periyodik olarak çağrılır. Sayaç değeri arttırılır, ve eğer maksimum değere ulaştıysa zamanlayıcı durdurulur.

Wx::Slider
Bu bir sürgü gibi tutup sağa sola çekerek bir değeri değiştirmek için kullandığımız eleman. 
slider_wid.rb
require "wx"
GÖREV_ORANI = 50
class Örnek < Wx::Frame
  def initialize(*args)
    super(*args)
    init_UI
  end
  def init_UI
    set_size [350, 210]
    set_title "Wx::Slider"
    centre
    pnl = Wx::Panel.new self
    sizer = Wx::GridBagSizer.new 5, 5
    sld = Wx::Slider.new pnl, value: 200, min_value: 150, max_value: 500,
                        style: Wx::SL_HORIZONTAL
    sld.evt_scroll { |e| on_slider_scroll e }
    sizer.add sld, Wx::GBPosition.new(0,0), Wx::DEFAULT_SPAN, 
                   Wx::ALL | Wx::EXPAND, 25
    @txt = Wx::StaticText.new pnl, label: '200'
    sizer.add @txt, Wx::GBPosition.new(0,1), Wx::DEFAULT_SPAN, 
                    Wx::TOP | Wx::RIGHT, 25
    sizer.add_growable_col 0
    pnl.sizer = sizer
  end
  def on_slider_scroll(e)
    obj = e.event_object
    val = obj.value
    @txt.label = val.to_s
  end
end
Wx::App.run {
  Örnek.new(nil).show
}
Slider sürgüsünü kaydırarak elde edilen değer yazdırılıyor. 
    sld = Wx::Slider.new pnl, value: 200, min_value: 150, 
            max_value: 500, style: Wx::SL_HORIZONTAL
Slider üretim kodu. value , o anki değer. min_value ve max_value alt ve üst sınırlar. 
    sld.evt_scroll { |e| on_slider_scroll e }
Scroll olayı slider sürgüsü kaydırılınca oluşur.
  def on_slider_scroll(e)
    obj = e.event_object
    val = obj.value
    @txt.label = val.to_s
  end
Slider value değerini yazdırır, hani yukarının yerine direk
    sld.evt_scroll { @txt.label = sld.value.to_s }
Yazsak da olurdu ama örneğimiz biraz da daha çaplı bir olay işleme gerekince nasıl yapılanılacağını göstermek için.

Wx::SpinCtrl
Wx::SpinCtrl elemanı bir değeri arttırıp eksiltmek amacıyla kullandığımız elemandır. 
spin_ctrl.rb
require "wx"
require "./my_wx_helper"
GÖREV_ORANI = 50
class Örnek < Wx::Frame
  def initialize(*args)
    super(*args)
    init_UI
  end
  def init_UI
    #set_size [350, 210]
    set_title "Wx::SpinCtrl"
    centre
    pnl = Wx::Panel.new self
    sizer = Wx::GridBagSizer.new 5, 5
    st1 = Wx::StaticText.new pnl, label: "Fahrenheit sıcaklığı Celsius'a dönüştürün"
    sizer.add st1, [0, 0], [1, 2], Wx::ALL, 15
    st2 = Wx::StaticText.new pnl, label: 'Fahrenheit:'
    sizer.add st2, [1, 0], Wx::DEFAULT_SPAN, Wx::ALL | Wx::ALIGN_CENTER, 15
        
    @sc = Wx::SpinCtrl.new pnl, value: '0'
    @sc.set_range(-459, 1000)
    sizer.add @sc, [1, 1], [0, 0], Wx::ALIGN_CENTER
    st3 = Wx::StaticText.new pnl, label: 'Celsius:'
    sizer.add st3, [2, 0], [0, 0], Wx::ALL|Wx::ALIGN_RIGHT, 15
    @celsius = Wx::StaticText.new pnl, label:''
    sizer.add @celsius, [2, 1], [0, 0], Wx::ALL, 15
    compute_button = Wx::Button.new pnl, label: 'Hesapla'
    compute_button.set_focus
    sizer.add compute_button, [3, 0], [0, 0], Wx::ALIGN_RIGHT|Wx::TOP, 30
    close_button = Wx::Button.new pnl, label: 'Kapat'
    sizer.add close_button, [3, 1], [0, 0], Wx::ALIGN_LEFT|Wx::TOP, 30
    evt_button compute_button, :on_compute 
    evt_button(close_button) { close }
    pnl.sizer = sizer
  end
  def on_compute(e)
    fahr = @sc.value
    cels = (fahr - 32) * 5 / 9.0
    @celsius.label = cels.round(2).to_s
  end
end
Wx::App.run {
  Örnek.new(nil).show
}
Burada GridBagSizer boyutlandırıcısı add metodunu değiştiren bir helper dosyam var, daha önce bahsetmiştim.
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 sayede pos ve span değerlerini daha basit girebiliyorum. 
    @sc = Wx::SpinCtrl.new pnl, value: '0'
    @sc.set_range(-459, 1000)
Spin kontrolümüzü bir başlangıç değeriyle oluşturuyoruz, alt ve üst sınırlarını set_range ile veriyoruz. 
Spin kontrolü bir özelliği de direk kutu içine sayı da yazabiliriz, ille yukarı-aşağı butonlarını kullanmak zorunda değiliz. set_increment metodu ile (veya increment= ) her tıklayıştaki artış miktarını belirleriz. 

Temel widget'lar bunlar. Sonraki bölümde gelişmiş widget'lar ile devam edeceğiz inşallah, şimdilik kalın sağlıcakla..
 
Hiç yorum yok:
Yorum Gönder