https://ujk-ujk.blogspot.com/2025/03/wxruby3-ile-masaustu-uygulama_29.html
Selam, WxRuby öğrenmeye kendi widget'larımızı üreterek devam ediyoruz.
Kendi Wx Nesnemizi Tanımlamak
GUI araç kitlerinde genelde button'lar, text widget'lar, scrollbar'lar, slider'lar gibi temel elemanlar olur. Her istediğimizi barındırmaları mümkün değil tabi ki. Daha gelişmiş elemanları programcı kendi üretir.
Kendi widget'ımızı iki yolla üretebiliriz. Ya mevcut bir nesneyi değiştiririz ya da sıfırdan yeni bir widget tanımlarız.
Bir Hyperlink nesnesi
İlk örneğimizde bir link yazısı nesnesi yapacağız. Bunu geliştirirken mevcut olan Wx::StaticText nesnesini kullanacağız.
hyperlink.rb
require "wx"
class Link < Wx::StaticText
def initialize(*args)
super *args
@font1 = Wx::Font.new 11, Wx::FONTFAMILY_SWISS, Wx::FONTSTYLE_NORMAL,
Wx::FONTWEIGHT_BOLD, true, 'Verdana'
@font1 = Wx::Font.new Wx::FontInfo.new(11).bold.underlined.
family(Wx::FONTFAMILY_SWISS).face_name('Verdana')
@font2 = Wx::Font.new 11, Wx::FONTFAMILY_SWISS, Wx::FONTSTYLE_NORMAL,
Wx::FONTWEIGHT_BOLD, false, 'Verdana'
@font2 = Wx::Font.new Wx::FontInfo.new(11).bold.
family(Wx::FONTFAMILY_SWISS).face_name('Verdana')
set_font @font2
set_foreground_colour '#0000ff'
evt_mouse_events :on_mouse_event
evt_motion :on_mouse_event
end
def url=(url)
@url = url
end
def on_mouse_event(e)
if e.moving
set_cursor Wx::Cursor.new(Wx::CURSOR_HAND)
set_font @font1
elsif e.left_up
system "start #{@url}"
else
set_cursor Wx::NULL_CURSOR
set_font @font2
end
e.skip
end
end
class Örnek < Wx::Frame
def initialize(*args)
super(*args)
init_UI
end
def init_UI
set_size [450, 150]
set_title "Kendi Widget'ım"
centre
panel = Wx::Panel.new self
vbox = Wx::BoxSizer.new Wx::VERTICAL
hbox = Wx::BoxSizer.new Wx::HORIZONTAL
st = Wx::StaticText.new panel, label: 'Web sitesine gidiniz:'
st.font = Wx::Font.new Wx::FontInfo.new(11).bold.
family(Wx::FONTFAMILY_SWISS).face_name('Verdana')
hbox.add st, 0, Wx::LEFT, 20
link_wid = Link.new panel, label: 'Boş Gezenin Boş Kalfası'
link_wid.url = 'http://www.ujk-ujk.blogspot.com'
hbox.add link_wid, 0, Wx::LEFT, 20
vbox.add hbox, 0, Wx::TOP, 30
panel.sizer = vbox
end
end
Wx::App.run {
Örnek.new(nil).show
}
Hyperlink widget'ımız mevcut bir widget'dan yapıldı. Hazır bir sınıfı alıp küçük modifikasyonlar yaptık.
set_font @font2
set_foreground_colour '#0000ff'
Link nesnemizin yazı rengini mavi olarak belirliyoruz.
@font1 = Wx::Font.new 11, Wx::FONTFAMILY_SWISS, Wx::FONTSTYLE_NORMAL,
Wx::FONTWEIGHT_BOLD, true, 'Verdana'
@font1 = Wx::Font.new Wx::FontInfo.new(11).bold.underlined.
family(Wx::FONTFAMILY_SWISS).face_name('Verdana')
@font2 = Wx::Font.new 11, Wx::FONTFAMILY_SWISS, Wx::FONTSTYLE_NORMAL,
Wx::FONTWEIGHT_BOLD, false, 'Verdana'
@font2 = Wx::Font.new Wx::FontInfo.new(11).bold.
family(Wx::FONTFAMILY_SWISS).face_name('Verdana')
Burada örnek olsun diye @font1 (altı çizili yazı) ve @font2 (normal yazı) fontlarının üretimini iki değişik teknikte gösterdim, istediğimizi kullanabiliriz, fikir olsun.
if e.moving
set_cursor Wx::Cursor.new(Wx::CURSOR_HAND)
set_font @font1
movig değeri bir mouse olay nesnesinde , mouse'un obje üzerinde olduğu ve butonlarının basılı olmadığını gösterir, buton basılıysa dragging özelliği true olur. Kursör yazı üzerine gelince "el" şeklini alıyor ve yazı altı çizgili font'a geçiyor.
elsif e.left_up
system "start #{@url}"
Link üzerinde tıklanıp bırakınca bir sistem komutuyla web sayfası @url adresini sistemde default tarayıcıda açarız.

Bu örnekte bir widget'ı baştan tanımlayacağız. Pencere altına bir Wx::Panel nesnesi yerleştirip yeni widget'ımızı orada çizeceğiz. Eğer bir CD ya da DVD yazıyorsanız buna benzer bir şey görürsünüz.
burning.rb
require "wx"
class Burning < Wx::Panel
def initialize(parent)
super parent, size: [-1, 30], style: Wx::SUNKEN_BORDER
@parent = parent
@font = Wx::Font.new 9, Wx::FONTFAMILY_DEFAULT, Wx::FONTSTYLE_NORMAL,
Wx::FONTWEIGHT_NORMAL, false, 'Courier 10 Pitch'
evt_paint :on_paint
evt_size :on_size
end
def on_paint(e)
num = (75..700).step(75).to_a
self.paint do |dc|
dc.set_font @font
w, h = get_size
@cw = @parent.get_parent.cw
step = (w / 10.0).round.to_i
j = 0
till = (w / 750.0 * @cw).to_i
full = (w / 750.0 * 700).to_i
if @cw >= 700
dc.pen = Wx::Pen.new '#FFFFB8'
dc.brush = Wx::Brush.new '#FFFFB8'
dc.draw_rectangle 0, 0, full, 30
dc.pen = Wx::Pen.new '#ffafaf'
dc.brush = Wx::Brush.new '#ffafaf'
dc.draw_rectangle full, 0, till-full, 30
else
dc.pen = Wx::Pen.new '#FFFFB8'
dc.brush = Wx::Brush.new '#FFFFB8'
dc.draw_rectangle 0, 0, till, 30
end
dc.pen = Wx::Pen.new '#5C5142'
(step..10*step).step(step).each do |i|
dc.draw_line i, 0, i, 6
width, height = dc.get_text_extent num[j].to_s
dc.draw_text num[j].to_s, i-width/2, 8
j = j + 1
end
end
end
def on_size(e)
refresh
end
end
class Örnek < Wx::Frame
attr_accessor :cw
def initialize(*args)
super(*args)
init_UI
end
def init_UI
set_size [350, 250]
set_title "Kendi Widget'ım"
centre
@cw = 75
panel = Wx::Panel.new self
center_panel = Wx::Panel.new panel
@sld = Wx::Slider.new center_panel, Wx::ID_ANY, 75, 0, 750,
size: [200, -1], style: Wx::SL_LABELS
vbox = Wx::BoxSizer.new Wx::VERTICAL
hbox = Wx::BoxSizer.new Wx::HORIZONTAL
hbox2 = Wx::BoxSizer.new Wx::HORIZONTAL
hbox3 = Wx::BoxSizer.new Wx::HORIZONTAL
@wid = Burning.new panel
hbox.add @wid, 1, Wx::EXPAND
hbox2.add center_panel, 1, Wx::EXPAND
hbox3.add @sld, 0, Wx::LEFT|Wx::TOP, 35
center_panel.sizer = hbox3
vbox.add hbox2, 1, Wx::EXPAND
vbox.add hbox, 0, Wx::EXPAND
evt_scroll :on_scroll
panel.sizer = vbox
@sld.set_focus
end
def on_scroll(e)
@cw = @sld.value
@wid.refresh
end
end
Wx::App.run {
Örnek.new(nil).show
}
Bu widget ile örneğin CD'de dolu alanı ve kalanı görebiliyoruz. Widget görünümünü bir slider değerine göre değiştiriyoruz. Eğer değer 700'ü geçerse renk kırmızıya geçiyor.
w, h = get_size
@cw = @parent.get_parent.cw
....
till = (w / 750.0 * @cw).to_i
full = (w / 750.0 * 700).to_i
Widget boyaması pencere boyutu ile orantılı oluyor. İçinde bulunulan pencereden @cw (yani slider) değerini alıyoruz. till değişkeninde o anki değere karşı widget ne kadarı boyanacağı var. full değişkeninde is nereden sonra kırmızı renge geçileceğiz var.
Boyama 3 adımda oluyor, önce sarı bölge dikdörtgen olarak çiziliyor, sonra varsa kırmızı bölüm dikdörtgen olarak çiziliyor, en son hepsinin üzerine cetvel çizgileri ve skala yazıları yazılıyor.
def on_size(e)
refresh
end
Pencere boyutu değişirse widget'ımızı tekrar boyuyoruz.
def on_scroll(e)
@cw = @sld.value
@wid.refresh
end
Slider kaydırılınca değerini @cw değişkenine alıyoruz ve widget'ımız @wid nesnesini tekrar boyuyoruz.

CPU nesnesi
Bazı uygulamalar vardır , CPU kullanımı, sıcaklık, hafıza kullanımı vs. sistem bilgilerini gösterir. Özelleştirilmiş widget'lar uygulamayı daha çekici yapar.
Aşağıdaki widget sistem uygulamalarında kullanılabilir.
cpu.rb
require "wx"
class CPU < Wx::Panel
def initialize(parent)
super parent, size: [80, 110]
@parent = parent
set_background_colour '#000000'
evt_paint :on_paint
end
def on_paint(e)
self.paint do |dc|
dc.set_device_origin 0, -100
dc.set_axis_orientation true, true
pos = parent.get_parent.get_parent.sel
rect = pos / 5
(1..21).each do |i|
if i > rect
dc.brush = Wx::Brush.new '#075100'
dc.draw_rectangle 10, i*4, 30, 5
dc.draw_rectangle 41, i*4, 30, 5
else
dc.brush = Wx::Brush.new '#36ff27'
dc.draw_rectangle 10, i*4, 30, 5
dc.draw_rectangle 41, i*4, 30, 5
end
end
end
end
end
class Örnek < Wx::Frame
attr_accessor :sel
def initialize(*args)
super(*args)
init_UI
end
def init_UI
set_size [350, 250]
set_title "CPU"
centre
@sel = 0
panel = Wx::Panel.new self
center_panel = Wx::Panel.new panel
@cpu = CPU.new center_panel
hbox = Wx::BoxSizer.new Wx::HORIZONTAL
@slider = Wx::Slider.new panel, Wx::ID_ANY, @sel, 0, 100,
size: [-1, 100], style: Wx::VERTICAL | Wx::SL_INVERSE
@slider.set_focus
hbox.add center_panel, 0, Wx::LEFT | Wx::TOP, 20
hbox.add @slider, 0, Wx::LEFT | Wx::TOP, 30
panel.sizer = hbox
evt_scroll :on_scroll
end
def on_scroll(e)
@sel = e.get_int
@cpu.refresh
end
end
Wx::App.run {
Örnek.new(nil).show
}
Siyah bir panel yapıp içine ince dikdörtgenler çizdik. Dikdörtgenlerin renkleri slider değerine göre değişiyor.
dc.set_device_origin 0, -100
dc.set_axis_orientation true, true
Bu satırlar koordinatları sol alta göre hesaplamak üzerine yazılmış Bunun yerine dikdörtgenler çizerken basit bir hesapla da aşağıdan yukarıya doğru çizilmesi sağlanabilirdi.
pos = parent.get_parent.get_parent.sel
rect = pos / 5
Slider pozisyonunu içinde bulunduğumuz pencerenin @sld değerinden alıyoruz. Slider 0-100 arası olup bizde 20 dikdörtgen boyanacağı için değeri 5'e bölüp parlak renkli dikdörtgen sayısını buluyoruz.
attr_accessor :sel
Bu satır sayesinde dışarıdan nesne oluşum değişkeni @sld'ye erişebiliyoruz.
(1..21).each do |i|
if i > rect
dc.brush = Wx::Brush.new '#075100'
dc.draw_rectangle 10, i*4, 30, 5
dc.draw_rectangle 41, i*4, 30, 5
else
dc.brush = Wx::Brush.new '#36ff27'
dc.draw_rectangle 10, i*4, 30, 5
dc.draw_rectangle 41, i*4, 30, 5
end
end
rect değerine kadar parlak yeşil , sonrası silik yeşil 21 çift dikdörtgen çiziyoruz.
İşte orijin değiştirmeden eksen döndürmeden burada draw_rectangle metodunun sadece 2. argümanlarına müdahale edip default eksenlerde de çizebiliriz.
#dc.set_device_origin 0, -100
#dc.set_axis_orientation true, true
pos = parent.get_parent.get_parent.sel
rect = pos / 5
(1..21).each do |i|
if i > rect
dc.brush = Wx::Brush.new '#075100'
dc.draw_rectangle 10, 100-i*4, 30, 5
dc.draw_rectangle 41, 100-i*4, 30, 5
else
dc.brush = Wx::Brush.new '#36ff27'
dc.draw_rectangle 10, 100-i*4, 30, 5
dc.draw_rectangle 41, 100-i*4, 30, 5
end
end
Çıktımız

WxRuby Uygulama Şablonları
Eğlenceli bir bölüme daha girdik. Şimdiye kadar hep elemanları gördük ama pek de uygulama gibi görünmüyorlardı. Bu bölümde bazı iyi tanıdığımız uygulamaların benzerlerini WxRuby kullanarak nasıl yaparız, onu deneyeceğiz.
Dosya yöneticisi
File Hunter bir dosya yöneticinin iskeleti. Unix sistemlerdeki Krusader dosya yöneticisinin görünümünü canlandırıyor. Splitter widget üzerinde çift tıklarsak pencereyi eşit genişlikte iki parçaya ayırır. Pencereyi yeniden boyutlandırırsak aynı şey olur.
file_hunter.rb
require "wx"
ID_BUTTON = 100
ID_EXIT = 200
ID_SPLITTER = 300
class MyListCtrl < Wx::ListCtrl
def initialize(parent)
super parent, style: Wx::LC_REPORT
insert_column 0, 'Name'
insert_column 1, 'Ext'
insert_column 2, 'Size', Wx::LIST_FORMAT_RIGHT
insert_column 3, 'Modified'
set_column_width 0, 150
set_column_width 1, 50
set_column_width 2, 100
set_column_width 3, 250
il = Wx::ImageList.new 16, 16
il.add Wx::Bitmap.new(Wx::ArtProvider.get_bitmap(Wx::ART_MISSING_IMAGE, Wx::ART_OTHER, [16,16]))
il.add Wx::BitmapBundle.from_svg_file("images/folder.svg", [16, 16] ).bitmap([16, 16])
il.add Wx::BitmapBundle.from_svg_file("images/source-rb.svg", [16, 16] ).bitmap([16, 16])
il.add Wx::BitmapBundle.from_svg_file("images/image.svg", [16, 16] ).bitmap([16, 16])
il.add Wx::BitmapBundle.from_svg_file("images/pdf.svg", [16, 16] ).bitmap([16, 16])
il.add Wx::Bitmap.new(Wx::ArtProvider.get_bitmap(Wx::ART_GO_UP, Wx::ART_OTHER, [16,16]))
set_image_list il, Wx::IMAGE_LIST_SMALL
j = 1
insert_item 0, '..'
set_item_image 0, 5
files = Dir.children(".")
files.each do |i|
name = File.basename(i)
ex = File.extname(i)[1..]
size = File.size(i)
sec = File.mtime(i)
insert_item j, name
set_item j, 1, ex.to_s
set_item j, 2, size.to_s + ' B'
set_item j, 3, sec.strftime('%Y-%m-%d %H:%M')
if File.directory?(i)
set_item_image j, 1
elsif ex == 'rb'
set_item_image j, 2
elsif ex == 'jpg' or ex == 'png'
set_item_image j, 3
elsif ex == 'pdf'
set_item_image j, 4
else
set_item_image j, 0
end
if (j % 2) == 0
set_item_background_colour j, '#e6f1f5'
end
j += 1
end
end
end
class Örnek < Wx::Frame
attr_accessor :sel
def initialize(*args)
super(*args)
init_UI
end
def init_UI
set_size [800, 300]
set_title "File Hunter"
centre
@splitter = Wx::SplitterWindow.new self, ID_SPLITTER, style: Wx::SP_BORDER
@splitter.minimum_pane_size = 50
p1 = MyListCtrl.new @splitter
p2 = MyListCtrl.new @splitter
@splitter.split_vertically p1, p2
evt_size :on_size
evt_splitter_dclick ID_SPLITTER, :on_double_click
filemenu= Wx::Menu.new
filemenu.append Wx::ID_EXIT, "E&xit"," Terminate the program"
editmenu = Wx::Menu.new
netmenu = Wx::Menu.new
showmenu = Wx::Menu.new
configmenu = Wx::Menu.new
helpmenu = Wx::Menu.new
menu_bar = Wx::MenuBar.new
menu_bar.append filemenu, "&File"
menu_bar.append editmenu, "&Edit"
menu_bar.append netmenu, "&Net"
menu_bar.append showmenu, "&Show"
menu_bar.append configmenu, "&Config"
menu_bar.append helpmenu, "&Help"
set_menu_bar menu_bar
evt_menu(ID_EXIT) { close }
tb = create_tool_bar Wx::TB_HORIZONTAL | Wx::NO_BORDER |
Wx::TB_FLAT
tb.add_tool 10, 'Previous',
Wx::Bitmap.new(Wx::ArtProvider.get_bitmap(Wx::ART_GO_BACK)), 'Previous'
tb.add_tool 20, 'Up',
Wx::Bitmap.new(Wx::ArtProvider.get_bitmap(Wx::ART_GO_UP)), 'Up one directory'
tb.add_tool 30, 'Home',
Wx::Bitmap.new(Wx::ArtProvider.get_bitmap(Wx::ART_GO_HOME)), 'Home'
tb.add_tool 40, 'Refresh',
Wx::BitmapBundle.from_svg_file("images/refresh.svg", [16, 16] ).bitmap([16, 16]), 'Refresh'
tb.add_separator
tb.add_tool 50, 'Edit text',
Wx::BitmapBundle.from_svg_file("images/edit.svg", [16, 16] ).bitmap([16, 16]), 'Edit text'
tb.add_tool 60, 'Terminal',
Wx::BitmapBundle.from_svg_file("images/display.svg", [16, 16] ).bitmap([16, 16]), 'Terminal'
tb.add_separator
tb.add_tool 70, 'Help',
Wx::Bitmap.new(Wx::ArtProvider.get_bitmap(Wx::ART_HELP)), 'Show help'
tb.realize
sizer2 = Wx::BoxSizer.new Wx::HORIZONTAL
button1 = Wx::Button.new self, ID_BUTTON + 1, "F3 View"
button2 = Wx::Button.new self, ID_BUTTON + 2, "F4 Edit"
button3 = Wx::Button.new self, ID_BUTTON + 3, "F5 Copy"
button4 = Wx::Button.new self, ID_BUTTON + 4, "F6 Move"
button5 = Wx::Button.new self, ID_BUTTON + 5, "F7 Mkdir"
button6 = Wx::Button.new self, ID_BUTTON + 6, "F8 Delete"
button7 = Wx::Button.new self, ID_BUTTON + 7, "F9 Rename"
button8 = Wx::Button.new self, ID_EXIT, "F10 Quit"
sizer2.add button1, 1, Wx::EXPAND
sizer2.add button2, 1, Wx::EXPAND
sizer2.add button3, 1, Wx::EXPAND
sizer2.add button4, 1, Wx::EXPAND
sizer2.add button5, 1, Wx::EXPAND
sizer2.add button6, 1, Wx::EXPAND
sizer2.add button7, 1, Wx::EXPAND
sizer2.add button8, 1, Wx::EXPAND
evt_button(ID_EXIT) { close }
sizer = Wx::BoxSizer.new Wx::VERTICAL
sizer.add @splitter, 1, Wx::EXPAND
sizer.add sizer2, 0, Wx::EXPAND
set_sizer sizer
sb = create_status_bar
sb.status_text = Dir.pwd
end
def on_size(e)
size = get_size
@splitter.sash_position = size.x / 2
e.skip
end
def on_double_click(e)
size = get_size
@splitter.sash_position = size.x / 2
end
end
Wx::App.run {
Örnek.new(nil).show
}
Koda bak maşallah 180 satırı buldu. İşte böyle böyle binlerce satırı buluyor.
class MyListCtrl < Wx::ListCtrl
def initialize(parent)
super parent, style: Wx::LC_REPORT
Uygulama esas elemanı Wx::ListCtrl'den türetildi.
il = Wx::ImageList.new 16, 16
il.add Wx::Bitmap.new(Wx::ArtProvider.get_bitmap(Wx::ART_MISSING_IMAGE, Wx::ART_OTHER, [16,16]))
il.add Wx::BitmapBundle.from_svg_file("images/folder.svg", [16, 16] ).bitmap([16, 16])
il.add Wx::BitmapBundle.from_svg_file("images/source-rb.svg", [16, 16] ).bitmap([16, 16])
il.add Wx::BitmapBundle.from_svg_file("images/image.svg", [16, 16] ).bitmap([16, 16])
il.add Wx::BitmapBundle.from_svg_file("images/pdf.svg", [16, 16] ).bitmap([16, 16])
il.add Wx::Bitmap.new(Wx::ArtProvider.get_bitmap(Wx::ART_GO_UP, Wx::ART_OTHER, [16,16]))
set_image_list il, Wx::IMAGE_LIST_SMALL
Listemizde dosya türlerini göstermek için bir Wx::ImageList içinde ikonlarımızı topluyoruz. Burada hem hazırda bulunan ART grafiklerini hem de svg dosyalardaki grafikleri nasıl bitmap'e çevirip ikon olarak kullanacağımızı gösterdim. Bu svg dosyalarını nereden bulduğumu sorarsanız, aşağıdaki başlığa bakınız.
files = Dir.children(".")
files.each do |i|
name = File.basename(i)
ex = File.extname(i)[1..]
size = File.size(i)
sec = File.mtime(i)
.....
Bulunduğumuz klasörden dosya isimlerini topladık. Her dosyanın ayrıntısını , name değeri dosya adını, ex değeri dosya uzantısını, size değeri dosya boyutunu ve sec değeri dosyanın en son ellendiği zamanı gösterecek şekilde topladık. Ruby'nin File sınıfının ne çok işe yaradığını görüyorsunuz.
if File.directory?(i)
set_item_image j, 1
elsif ex == 'rb'
set_item_image j, 2
elsif ex == 'jpg' or ex == 'png'
set_item_image j, 3
elsif ex == 'pdf'
set_item_image j, 4
else
set_item_image j, 0
end
Dosyanın uzantısına göre onu sembolize eden image listeden getiriliyor.
@splitter = Wx::SplitterWindow.new self, ID_SPLITTER, style: Wx::SP_BORDER
@splitter.minimum_pane_size = 50
p1 = MyListCtrl.new @splitter
p2 = MyListCtrl.new @splitter
@splitter.split_vertically p1, p2
İki tane listeyi bir SplitterWindow nesnesinin iki yanına yerleştiriyoruz.
menu_bar = Wx::MenuBar.new
menu_bar.append filemenu, "&File"
menu_bar.append editmenu, "&Edit"
menu_bar.append netmenu, "&Net"
....
Bir MenuBar'ımız da var.
tb = create_tool_bar Wx::TB_HORIZONTAL | Wx::NO_BORDER |
Wx::TB_FLAT
tb.add_tool 10, 'Previous',
Wx::Bitmap.new(Wx::ArtProvider.get_bitmap(Wx::ART_GO_BACK)), 'Previous'
tb.add_tool 20, 'Up',
Wx::Bitmap.new(Wx::ArtProvider.get_bitmap(Wx::ART_GO_UP)), 'Up one directory'
....
Araç kutularımız da var.
sizer2 = Wx::BoxSizer.new Wx::HORIZONTAL
button1 = Wx::Button.new self, ID_BUTTON + 1, "F3 View"
button2 = Wx::Button.new self, ID_BUTTON + 2, "F4 Edit"
button3 = Wx::Button.new self, ID_BUTTON + 3, "F5 Copy"
....
8 tane butonu bir yatay boyutlandırıcıda yan yana diziyoruz.

SVG dosyalarını ikon olarak kullanmak
Birçok uygulamada ikon dosyaları çok lazım oluyor. Bir işletim sisteminden ikonları yoplasam dedim. https://www.gnome-look.org/p/1998755 adresinde ikonların dosyasını indirdim. Dosya içindeki alt klasörlerden 16 dizinindeki her şeyi uygulamalarımı koyduğum klasöre kopyaladım. Bu klasörler içinde bulunan her svg dosyayı tek tek incelemek yerine bir Ruby program yazayım ve hepsini bir arada göreyim dedim.
require "wx"
require "clipboard"
class Örnek < Wx::Frame
def initialize(*args)
super(*args)
init_UI
end
def init_UI
set_size [460, 250]
set_title "Klasördeki SVG Dosyalar"
centre
files = Dir.children(File.dirname $0).grep(/.svg/)#[0..999]
#p files
@panel = Wx::ScrolledWindow.new self
@panel.set_scrollbars(20, 20, 50, 50)
@panel.background_colour = :white
vb = Wx::BoxSizer.new Wx::VERTICAL
hboxes = []
files.each_with_index do |v,i|
if i % 30 == 0
hboxes << Wx::BoxSizer.new(Wx::HORIZONTAL)
end
z = Wx::StaticBitmap.new @panel, Wx::ID_ANY,
Wx::BitmapBundle.from_svg_file(File.dirname($0) + "/" + v, [32,32])
z.tool_tip = v
hboxes.last.add z, 0, Wx::ALL, 5
z.evt_left_down do |e|
Clipboard.copy v
p "Kopyalandı"
end
if i % 30 == 29
vb.add hboxes.last
end
end
vb.add hboxes.last
@panel.sizer = vb
end
end
Wx::App.run {
Örnek.new(nil).show
}
Bu kod klasörde bulunan tüm .svg dosyaları gösteriyor. Bazı klasörlerde binlerce dosya olması dolayısıyla programı çalıştırınca biraz beklemeniz gerekebilir.

Bunun dışında bir de WxRuby'de kayıtlı ART ikonları toptan göreyim diye bir kod yazdım üşenmeden
art_images.rb
require "wx"
class Örnek < Wx::Frame
def initialize(*args)
super(*args)
init_UI
end
def init_UI
set_size [460, 250]
set_title "Basit Araç Kutusu"
centre
@panel = Wx::Panel.new self
@panel.background_colour = :gray
vb = Wx::BoxSizer.new Wx::VERTICAL
hb1 = Wx::BoxSizer.new Wx::HORIZONTAL
add_h Wx::ART_ADD_BOOKMARK, hb1
add_h Wx::ART_DEL_BOOKMARK, hb1
add_h Wx::ART_HELP_SIDE_PANEL, hb1
add_h Wx::ART_HELP_SETTINGS, hb1
add_h Wx::ART_HELP_BOOK, hb1
add_h Wx::ART_HELP_FOLDER, hb1
add_h Wx::ART_HELP_PAGE, hb1
add_h Wx::ART_GO_BACK, hb1
add_h Wx::ART_GO_FORWARD, hb1
add_h Wx::ART_GO_UP, hb1
add_h Wx::ART_GO_DOWN, hb1
add_h Wx::ART_GO_TO_PARENT, hb1
add_h Wx::ART_GO_HOME, hb1
add_h Wx::ART_GOTO_FIRST, hb1
add_h Wx::ART_GOTO_LAST, hb1
vb.add hb1
hb2 = Wx::BoxSizer.new Wx::HORIZONTAL
add_h Wx::ART_FILE_OPEN, hb2
add_h Wx::ART_FILE_SAVE, hb2
add_h Wx::ART_FILE_SAVE_AS, hb2
add_h Wx::ART_PRINT, hb2
add_h Wx::ART_HELP, hb2
add_h Wx::ART_TIP, hb2
add_h Wx::ART_REPORT_VIEW, hb2
add_h Wx::ART_LIST_VIEW, hb2
add_h Wx::ART_NEW_DIR, hb2
add_h Wx::ART_HARDDISK, hb2
add_h Wx::ART_FLOPPY, hb2
add_h Wx::ART_CDROM, hb2
add_h Wx::ART_REMOVABLE, hb2
vb.add hb2
hb3 = Wx::BoxSizer.new Wx::HORIZONTAL
add_h Wx::ART_FOLDER, hb3
add_h Wx::ART_FOLDER_OPEN, hb3
add_h Wx::ART_GO_DIR_UP, hb3
add_h Wx::ART_EXECUTABLE_FILE, hb3
add_h Wx::ART_NORMAL_FILE, hb3
add_h Wx::ART_TICK_MARK, hb3
add_h Wx::ART_CROSS_MARK, hb3
add_h Wx::ART_ERROR, hb3
add_h Wx::ART_QUESTION, hb3
add_h Wx::ART_WARNING, hb3
add_h Wx::ART_INFORMATION, hb3
add_h Wx::ART_MISSING_IMAGE, hb3
add_h Wx::ART_COPY, hb3
vb.add hb3
hb4 = Wx::BoxSizer.new Wx::HORIZONTAL
add_h Wx::ART_CUT, hb4
add_h Wx::ART_PASTE, hb4
add_h Wx::ART_DELETE, hb4
add_h Wx::ART_NEW, hb4
add_h Wx::ART_UNDO, hb4
add_h Wx::ART_REDO, hb4
add_h Wx::ART_PLUS, hb4
add_h Wx::ART_MINUS, hb4
add_h Wx::ART_CLOSE, hb4
add_h Wx::ART_QUIT, hb4
add_h Wx::ART_FIND, hb4
add_h Wx::ART_FIND_AND_REPLACE, hb4
add_h Wx::ART_FULL_SCREEN, hb4
vb.add hb4
hb5 = Wx::BoxSizer.new Wx::HORIZONTAL
add_h Wx::ART_EDIT, hb5
add_h Wx::ART_WX_LOGO, hb5
vb.add hb5
@panel.sizer = vb
end
def add_h(item, hbox)
a = Wx::StaticBitmap.new @panel, Wx::ID_ANY,
Wx::Bitmap.new(Wx::ArtProvider.get_bitmap(item))
a.set_tool_tip(item)
hbox.add a, 0, Wx::ALL, 5
end
end
Wx::App.run {
Örnek.new(nil).show
}
Bir ikonun üzerine gelince tooltip olarak hangi sabit değer olduğu görülür ve bu kodda görüldüğü gibi ikon olarak kullanılabilir.
.

E-tablo
Sıarada bir SpreadSheet uygulaması iskeleti var.
spreadsheet.rb
require "wx"
class MySheet < Wx::GRID::Grid
def initialize(*args)
super(*args)
init_UI
end
def init_UI
n_of_rows = 55
n_of_cols = 25
row = col = 0
create_grid n_of_rows, n_of_cols
set_col_label_size 20
set_row_label_size 50
evt_grid_select_cell :on_grid_select_cell
for i in (0...n_of_rows)
set_row_size i, 20
end
for i in (0...n_of_cols)
set_col_size i, 75
end
end
def on_grid_select_cell(e)
row, col = e.row, e.col
control = get_parent.get_parent.position_text
value = get_col_label_value(col) + get_row_label_value(row)
control.set_value value
e.skip
end
end
class Örnek < Wx::Frame
attr_accessor :position_text
def initialize(*args)
super(*args)
init_UI
end
def init_UI
set_size [550, 550]
set_title "E-Tablo"
centre
fonts = ['Times New Roman', 'Times', 'Courier', 'Courier New', 'Helvetica',
'Sans', 'verdana', 'utkal', 'aakar', 'Arial']
font_sizes = ['10', '11', '12', '14', '16']
box = Wx::BoxSizer.new Wx::VERTICAL
menu_bar = Wx::MenuBar.new
menu1 = Wx::Menu.new
menu_bar.append menu1, '&File'
menu2 = Wx::Menu.new
menu_bar.append menu2, '&Edit'
menu3 = Wx::Menu.new
menu_bar.append menu3, '&View'
menu4 = Wx::Menu.new
menu_bar.append menu4, '&Insert'
menu5 = Wx::Menu.new
menu_bar.append menu5, 'F&ormat'
menu6 = Wx::Menu.new
menu_bar.append menu6, '&Tools'
menu7 = Wx::Menu.new
menu_bar.append menu7, '&Data'
menu8 = Wx::Menu.new
menu_bar.append menu8, '&Help'
set_menu_bar menu_bar
toolbar1 = Wx::ToolBar.new self, style: Wx::TB_HORIZONTAL
toolbar1.add_tool Wx::ID_ANY, '',
Wx::Bitmap.new(Wx::ArtProvider.get_bitmap(Wx::ART_NEW)), "New"
toolbar1.add_tool Wx::ID_ANY, '',
Wx::Bitmap.new(Wx::ArtProvider.get_bitmap(Wx::ART_FILE_OPEN)), "Open"
toolbar1.add_tool Wx::ID_ANY, '',
Wx::Bitmap.new(Wx::ArtProvider.get_bitmap(Wx::ART_FILE_SAVE)), "Save"
toolbar1.add_separator
toolbar1.add_tool Wx::ID_ANY, '',
Wx::Bitmap.new(Wx::ArtProvider.get_bitmap(Wx::ART_CUT)), "Cut"
toolbar1.add_tool Wx::ID_ANY, '',
Wx::Bitmap.new(Wx::ArtProvider.get_bitmap(Wx::ART_COPY)), "Copy"
toolbar1.add_tool Wx::ID_ANY, '',
Wx::Bitmap.new(Wx::ArtProvider.get_bitmap(Wx::ART_PASTE)), "Paste"
toolbar1.add_tool Wx::ID_ANY, '',
Wx::Bitmap.new(Wx::ArtProvider.get_bitmap(Wx::ART_DELETE)), "Delete"
toolbar1.add_separator
toolbar1.add_tool Wx::ID_ANY, '',
Wx::Bitmap.new(Wx::ArtProvider.get_bitmap(Wx::ART_UNDO)), "Undo"
toolbar1.add_tool Wx::ID_ANY, '',
Wx::Bitmap.new(Wx::ArtProvider.get_bitmap(Wx::ART_REDO)), "Redo"
toolbar1.add_separator
toolbar1.add_tool Wx::ID_ANY, '',
Wx::BitmapBundle.from_svg_file("images/ascending-name.svg", [16, 16] ).
bitmap([16, 16]), 'Ascending'
toolbar1.add_tool Wx::ID_ANY, '',
Wx::BitmapBundle.from_svg_file("images/descending-name.svg", [16, 16] ).
bitmap([16, 16]), 'Descending'
toolbar1.add_separator
toolbar1.add_tool Wx::ID_ANY, '',
Wx::BitmapBundle.from_svg_file("images/chart.svg", [16, 16] ).
bitmap([16, 16]), 'Chart'
toolbar1.add_separator
toolbar1.add_tool Wx::ID_EXIT, '',
Wx::Bitmap.new(Wx::ArtProvider.get_bitmap(Wx::ART_QUIT)), "Exit"
toolbar1.realize
toolbar2 = Wx::ToolBar.new self, Wx::TB_HORIZONTAL | Wx::TB_TEXT
@position_text = Wx::TextCtrl.new toolbar2
font_combo = Wx::ComboBox.new toolbar2, value: 'Times', choices: fonts,
size: [100, -1], style: Wx::CB_DROPDOWN
font_height = Wx::ComboBox.new toolbar2, value: '10', choices: font_sizes,
size: [50, -1], style: Wx::CB_DROPDOWN
toolbar2.add_control position_text
toolbar2.add_control font_combo
toolbar2.add_control font_height
toolbar2.add_separator
toolbar2.add_check_tool Wx::ID_ANY, '',
Wx::BitmapBundle.from_svg_file("images/text-bold.svg", [16, 16] ).
bitmap([16, 16])
toolbar2.add_check_tool Wx::ID_ANY, '',
Wx::BitmapBundle.from_svg_file("images/text-italic.svg", [16, 16] ).
bitmap([16, 16])
toolbar2.add_check_tool Wx::ID_ANY, '',
Wx::BitmapBundle.from_svg_file("images/text-underline.svg", [16, 16] ).
bitmap([16, 16])
toolbar2.add_separator
toolbar2.add_tool Wx::ID_ANY, '',
Wx::BitmapBundle.from_svg_file("images/justify-left.svg", [16, 16] ).
bitmap([16, 16]), "Align Left"
toolbar2.add_tool Wx::ID_ANY, '',
Wx::BitmapBundle.from_svg_file("images/justify-center.svg", [16, 16] ).
bitmap([16, 16]), "Align Center"
toolbar2.add_tool Wx::ID_ANY, '',
Wx::BitmapBundle.from_svg_file("images/justify-right.svg", [16, 16] ).
bitmap([16, 16]), "Align Right"
toolbar2.realize
box.add toolbar1
box.add 5, 5, 0
box.add toolbar2
box.add 5, 10, 0
notebook = Wx::Notebook.new self, style: Wx::RIGHT
sheet1 = MySheet.new notebook
sheet2 = MySheet.new notebook
sheet3 = MySheet.new notebook
notebook.add_page sheet1, 'Sheet1'
notebook.add_page sheet2, 'Sheet2'
notebook.add_page sheet3, 'Sheet3'
box.add notebook, 1, Wx::EXPAND
set_sizer box
create_status_bar
end
end
Wx::App.run {
Örnek.new(nil).show
}
Örnek kodumuz OpenOffice Calc benzeri bir Etablo uygulamasının iskeletini gösteriyor. Menübarı toolbarı ve bir grid tablosu var.
class MySheet < Wx::GRID::Grid
def initialize(*args)
super(*args)
init_UI
end
def init_UI
n_of_rows = 55
n_of_cols = 25
row = col = 0
create_grid n_of_rows, n_of_cols
....
MySheet nesnemizi Wx::GRID::Grid nesnesinden kalıtımla üretiyoruz. Her sayfamızda 55 satır ve 26 sütun olacak. Hücrelerden oluşan grid, create_grid metodu ile üretiliyor.
control = get_parent.get_parent.position_text
Ana penceremizin position_text nesnesinde bulunulan hücrenin sütun ve satır değerini gösteriyoruz. Bu ikinci araç barında bulunuyor. Nesne özelliği olarak erişmek için @position_text olarak oluşum değişkeni olarak tanımlıyoruz ve dışardan elemana ulaşmak için
attr_accessor :position_text
satırını kodumuza ekledik. Sayfamız bir MySheet nesnesi ve o da notebook nesnesinin çocuğu, notebook nesnemizde Örnek sınıfından ürettiğimiz nesnenin çocuğu. Bu yüzden penceremize hücreye tıklanınca erişmek için get_parent.get_parent. şeklinde 2 parent yukarı çıkıyoruz.
notebook = Wx::Notebook.new self, style: Wx::RIGHT
sheet1 = MySheet.new notebook
sheet2 = MySheet.new notebook
sheet3 = MySheet.new notebook
notebook.add_page sheet1, 'Sheet1'
notebook.add_page sheet2, 'Sheet2'
notebook.add_page sheet3, 'Sheet3'
3 adet sayfamızdan üretip pencereye ekliyoruz. Bu uygulamamızda da önceki uygulamalardaki gibi Wx::ART ikonları ve svg ikonları karışık kullandım.

Player
Şimdiki örneğimiz bir video player örneği olacak
player.rb
require "wx"
class Örnek < Wx::Frame
def initialize(*args)
super(*args)
init_UI
end
def init_UI
set_title "Player"
centre
create_menu_bar
panel = Wx::Panel.new self
pnl1 = Wx::Panel.new self
pnl1.background_colour = :black
pnl2 = Wx::Panel.new self
slider1 = Wx::Slider.new pnl2, Wx::ID_ANY, 18, 0, 1000
pause = Wx::BitmapButton.new pnl2, -1, svg_to_bitmap_icon("images/media-pause.svg")
play = Wx::BitmapButton.new pnl2, -1, svg_to_bitmap_icon("images/media-play.svg")
fwd = Wx::BitmapButton.new pnl2, -1, svg_to_bitmap_icon("images/media-fwd.svg")
rew = Wx::BitmapButton.new pnl2, -1, svg_to_bitmap_icon("images/media-rew.svg")
mute = Wx::BitmapButton.new pnl2, -1, svg_to_bitmap_icon("images/voice.svg")
volume = Wx::Slider.new pnl2, -1, 1, 0, 100, size: [120, -1]
vbox = Wx::BoxSizer.new Wx::VERTICAL
hbox1 = Wx::BoxSizer.new Wx::HORIZONTAL
hbox2 = Wx::BoxSizer.new Wx::HORIZONTAL
hbox1.add slider1, 1
hbox2.add pause
hbox2.add play, 0, Wx::RIGHT, 5
hbox2.add fwd, 0, Wx::LEFT, 5
hbox2.add rew
hbox2.add -1, -1, 1
hbox2.add mute
hbox2.add volume, 0, Wx::TOP | Wx::LEFT, 5
vbox.add hbox1, 0, Wx::EXPAND | Wx::BOTTOM, 10
vbox.add hbox2, 1, Wx::EXPAND
pnl2.set_sizer vbox
sizer = Wx::BoxSizer.new Wx::VERTICAL
sizer.add pnl1, 1, Wx::EXPAND
sizer.add pnl2, 0, Wx::EXPAND | Wx::BOTTOM | Wx::TOP, 10
set_sizer sizer
set_min_size [350, 300]
create_status_bar
end
def create_menu_bar
menubar = Wx::MenuBar.new
filem = Wx::Menu.new
play = Wx::Menu.new
view = Wx::Menu.new
tools = Wx::Menu.new
favorites = Wx::Menu.new
help = Wx::Menu.new
filem.append Wx::ID_EXIT, "&Quit", "Quit Application"
menubar.append filem, '&File'
menubar.append play, '&Play'
menubar.append view, '&View'
menubar.append tools, '&Tools'
menubar.append favorites, 'F&avorites'
menubar.append help, '&Help'
end
def svg_to_bitmap_icon(file_name)
Wx::BitmapBundle.from_svg_file(file_name, [16, 16] ).bitmap([16, 16])
end
end
Wx::App.run {
Örnek.new(nil).show
}
Arabirimi yapmak için slider'lar bitmap butonlar ve menüler kullandık.
pnl1 = Wx::Panel.new self
pnl1.background_colour = :black
Uygulamanın ana elemanı siyah arka planlı bir panel nesnesi.
slider1 = Wx::Slider.new pnl2, Wx::ID_ANY, 18, 0, 1000
Slider nesnesi ile video ilerlemesini gösteriyoruz.
pause = Wx::BitmapButton.new pnl2, -1, svg_to_bitmap_icon("images/media-pause.svg")
play = Wx::BitmapButton.new pnl2, -1, svg_to_bitmap_icon("images/media-play.svg")
Kontrol butonları olarak BitmapButton nesneleri kullanıyoruz.
set_min_size [350, 300]
Pencere boyutlandırmasını minimum bir yerde sınırlıyor.

Tarayıcı
Şimdiki taslağımız da bir web tarayıcı görseli.
browser.rb
require "wx"
class Örnek < Wx::Frame
def initialize(*args)
super(*args)
init_UI
end
def init_UI
set_size [500, 350]
set_title "Tarayıcı"
centre
create_menu_bar
panel = Wx::Panel.new self
vbox = Wx::BoxSizer.new Wx::VERTICAL
hbox1 = Wx::BoxSizer.new Wx::HORIZONTAL
hbox2 = Wx::BoxSizer.new Wx::HORIZONTAL
line1 = Wx::StaticLine.new panel
vbox.add line1, 0, Wx::EXPAND
toolbar1 = Wx::Panel.new panel, size: [-1, 30]
back = Wx::BitmapButton.new toolbar1,
bitmap: Wx::Bitmap.new(Wx::ArtProvider.get_bitmap(Wx::ART_GO_BACK)),
style: Wx::NO_BORDER
forward = Wx::BitmapButton.new toolbar1,
bitmap: Wx::Bitmap.new(Wx::ArtProvider.get_bitmap(Wx::ART_GO_FORWARD)),
style: Wx::NO_BORDER
refresh = Wx::BitmapButton.new toolbar1,
bitmap: svg_to_bitmap_icon("images/refresh.svg"),
style: Wx::NO_BORDER
stop = Wx::BitmapButton.new toolbar1,
bitmap: svg_to_bitmap_icon("images/media-stop.svg"),
style: Wx::NO_BORDER
home = Wx::BitmapButton.new toolbar1,
bitmap: Wx::Bitmap.new(Wx::ArtProvider.get_bitmap(Wx::ART_GO_HOME)),
style: Wx::NO_BORDER
address = Wx::ComboBox.new toolbar1, size: [50, -1]
go = Wx::BitmapButton.new toolbar1,
bitmap: svg_to_bitmap_icon("images/media-play.svg"),
style: Wx::NO_BORDER
text = Wx::TextCtrl.new toolbar1, size: [150, -1]
hbox1.add back
hbox1.add forward
hbox1.add refresh
hbox1.add stop
hbox1.add home
hbox1.add address, 1, Wx::TOP, 3
hbox1.add go, 0, Wx::TOP|Wx::LEFT, 3
hbox1.add text, 0, Wx::TOP|Wx::RIGHT, 3
toolbar1.sizer = hbox1
vbox.add toolbar1, 0, Wx::EXPAND
line = Wx::StaticLine.new panel
vbox.add line, 0, Wx::EXPAND
toolbar2 = Wx::Panel.new panel, size: [-1, 30]
bookmark1 = Wx::BitmapButton.new toolbar2,
bitmap: svg_to_bitmap_icon("images/flag-blue.svg"),
style: Wx::NO_BORDER
bookmark2 = Wx::BitmapButton.new toolbar2,
bitmap: svg_to_bitmap_icon("images/source-rb.svg"),
style: Wx::NO_BORDER
bookmark3 = Wx::BitmapButton.new toolbar2,
bitmap: svg_to_bitmap_icon("images/playlist.svg"),
style: Wx::NO_BORDER
hbox2.add bookmark1, 0, Wx::RIGHT, 5
hbox2.add bookmark2, 0, Wx::RIGHT, 5
hbox2.add bookmark3
toolbar2.sizer = hbox2
vbox.add toolbar2, 0, Wx::EXPAND
line2 = Wx::StaticLine.new panel
vbox.add line2, 0, Wx::EXPAND
panel.sizer = vbox
create_status_bar
end
def create_menu_bar
menubar = Wx::MenuBar.new
filem = Wx::Menu.new
filem.append Wx::ID_EXIT, "&Quit", "Quit Application"
edit = Wx::Menu.new
view = Wx::Menu.new
go = Wx::Menu.new
bookmarks = Wx::Menu.new
tools = Wx::Menu.new
help = Wx::Menu.new
menubar.append filem, '&File'
menubar.append edit, '&Edit'
menubar.append view, '&View'
menubar.append go, '&Go'
menubar.append bookmarks, '&Bookmarks'
menubar.append tools, '&Tools'
menubar.append help, '&Help'
set_menu_bar menubar
end
def svg_to_bitmap_icon(file_name)
Wx::BitmapBundle.from_svg_file(file_name, [16, 16] ).bitmap([24, 24])
end
end
Wx::App.run {
Örnek.new(nil).show
}
Boyutlanabilir bir ComboBox elde edebilmek için ToolBar yerine panel üzerinde araç butonları oluşturduk.
toolbar1 = Wx::Panel.new panel, size: [-1, 30]
Düz bir Wx::Panel oluşturduk
hbox1 = Wx::BoxSizer.new Wx::HORIZONTAL
.....
hbox1.add back
hbox1.add forward
hbox1.add refresh
hbox1.add stop
Yatay bir boyutlandırıcı üzerine araç butonlarını yerleştirdik.
hbox1.add address, 1, Wx::TOP, 3
ComboBox nesnemizi pencere ile beraber boyutlanacak şekilde ekledik. Tarayıcılarda buna adres kutusu denir.
line2 = Wx::StaticLine.new panel
vbox.add line2, 0, Wx::EXPAND
Ana paneli yatay çizgilerle bölümlere ayırıyoruz.

Bu bölüm de burada bitti. Sonraki yazımda WxPython ile yazılmış bir programı WxRuby ile yazmaya çalışacağım nasipse. Şimdilik kalın sağlıcakla..
Hiç yorum yok:
Yorum Gönder