麻豆小视频在线观看_中文黄色一级片_久久久成人精品_成片免费观看视频大全_午夜精品久久久久久久99热浪潮_成人一区二区三区四区

首頁(yè) > 編程 > Ruby > 正文

進(jìn)行GTK之Ruby GUI編程的基本方法

2020-02-24 15:36:23
字體:
來(lái)源:轉(zhuǎn)載
供稿:網(wǎng)友

隨著RubyGNOMe2庫(kù)變得越來(lái)越完善,Ruby1.9的性能也得到了提高,在Ruby中編寫(xiě)GUI程序逐漸從我的愛(ài)好提高到了我工作的重要部分,本文是武林技術(shù)頻道小編為大家?guī)?lái)的進(jìn)行GTK之Ruby GUI編程的基本方法,一起來(lái)看看吧!
RubyGnome2介紹
?
雖然我以前也曾經(jīng)多次地介紹過(guò)RubyGnome2,但我還是想再一次地推薦RubyGnome2,它實(shí)在是使用Ruby編寫(xiě)GUI程序的首選。
?
RubyGnome2是GTK+庫(kù)的一個(gè)ruby擴(kuò)展。它對(duì)GTK+的對(duì)象模型仔細(xì)地用Ruby的方式進(jìn)行封裝,保留了GTK+ API命名方式和含義,因此GTK+的文檔對(duì)于RubyGnome2也是適用的---盡管我認(rèn)為RubyGnome2的文檔已經(jīng)做得非常不錯(cuò)了,需要回去借鑒GTK文檔的地方實(shí)在不多。
?
雖然GTK本身是由C編寫(xiě)的,但它有一套完整的精心設(shè)計(jì)對(duì)象體系,使得它的GUI元件可以非常靈活的自由組合,以實(shí)現(xiàn)復(fù)雜的,功能強(qiáng)大的界面。
?
由于GTK非常重視它的對(duì)象體系的靈活性,因此剛開(kāi)始使用GTK編程并不容易。很多時(shí)候表面上看起來(lái)很簡(jiǎn)單的一個(gè)功能,在GTK里面卻要繞幾個(gè)彎才能實(shí)現(xiàn)。例如要設(shè)置一個(gè)label的字體,要通過(guò)Pango來(lái)實(shí)現(xiàn),Pango接管了GTK的所有字體渲染事務(wù)....這種“多繞幾個(gè)彎”的情況很多,它確實(shí)使得編寫(xiě)GTK程序不那么直接了當(dāng)。但換來(lái)的是整個(gè)GTK系統(tǒng)變得非常靈活,以較少的代價(jià)實(shí)現(xiàn)強(qiáng)大的功能,在跨平臺(tái),換膚,國(guó)際化上面都有很好的表現(xiàn)。
?
RubyGnome2繼承了GTK的所有特點(diǎn),包括優(yōu)點(diǎn)和缺點(diǎn)。
?
GUI布局
GTK程序的布局很靈活,有許多種容器可選擇。在布局的時(shí)候,大多數(shù)都是推薦相對(duì)位置而不是絕對(duì)位置,這樣GUI程序可以更好的適應(yīng)不同分辨率的屏幕,也有利于特定風(fēng)格對(duì)UI的fine tune。
最常見(jiàn)的容器就是“盒子”,包括“水平盒子”和“垂直盒子”。將可視的UI元件放入“盒子”,不同的“盒子”互相組合疊放就可以構(gòu)建出目標(biāo)布局。
?
理論上用盒子就可以構(gòu)建任何相對(duì)位置布局,但是為了方面,GTK還提供了像table這樣的更高級(jí)的容器。
?
盒子模型對(duì)于許多剛開(kāi)始GTK編程的人覺(jué)得很難適應(yīng),即使用了可視化布局工具例如Glade,初學(xué)者也往往被盒子模型困擾。可視化布局器最擅長(zhǎng)的是固定位置布局。對(duì)于相對(duì)位置布局,很多時(shí)候用代碼構(gòu)建界面比用Glade反而來(lái)的快捷方便。
?
但是用代碼構(gòu)建界面有一個(gè)顯著的缺點(diǎn),那就是“不直觀”,即很難從代碼中看出UI布局,這樣會(huì)給后期維護(hù)以及變更帶來(lái)麻煩。
?
有一些GUI庫(kù)如Shose,用builder風(fēng)格的代碼來(lái)描述UI,使得UI布局可以通過(guò)代碼形象地體現(xiàn)出來(lái),如以下這個(gè)例子來(lái)自shooose.net:
?

Shoes.app {  stack(:margin => 4) {   button "Mice"   button "Eagles"   button "Quail"  } } 

?
?
這樣,我們就可以從代碼中一下子看出UI布局了。
?
builder風(fēng)格的代碼和HTML很類(lèi)似,對(duì)于熟悉HTML的web界面設(shè)計(jì)者來(lái)說(shuō),可視化的編輯器并沒(méi)有多大的必要。
?
?
RubyGnome2沒(méi)有為我們提供builder方式的布局,因此UI代碼寫(xiě)起來(lái)就像:
?

class MyWin < Gtk::Window  def initialize   super   vbox = Gtk::VBox.new   btn_mice = Gtk::Button.new 'Mice'   vbox.pack_start btn_mice   btn_eagles = Gtk::Button.new 'Eagles'   vbox.pack_start btn_eagles   btn_quail = Gtk::Button.new 'Quail'   vbox.pack_start btn_quail   add vbox  end end 

?
從上面的代碼中很難一下子看出UI布局。
?
如果也為RubyGnome2構(gòu)建一個(gè)builder風(fēng)格的布局器,那么代碼就會(huì)變成:
?

class MyWin < Gtk::Window   def initialize   super   add my_layout  end   def my_layout   vbox do    button 'Mice'    button 'Eagles'    button 'Quail'   end  end  end 

?
?
嗯,這個(gè)代碼就和Shose差不多了,可以從代碼中一眼看出UI布局。
?
本文所介紹的GtkSimpleLayout其功能之一就是為RubyGnome2提供builder風(fēng)格的布局器。
?
GtkSimpleLayout布局器
這個(gè)簡(jiǎn)單的布局器原先只有200行不到的代碼,我經(jīng)常是直接拷貝到項(xiàng)目中使用。后來(lái)逐漸添了些功能,覺(jué)得它變得更有用了,于是便發(fā)布到github生成gem,方便感興趣者使用。
?
Source: git://github.com/rickyzheng/GtkSimpleLayout.git
or:
gem source -a http://gems.github.com && gem install rickyzheng-GtkSimpleLayout
?
以下是主要功能介紹以及簡(jiǎn)單例子。
?
提供Builder風(fēng)格布局
正如上面的例子中所介紹的,GtkSimpleLayout為RubyGnome2帶來(lái)了builder風(fēng)格的布局功能,只需要為布局的類(lèi)擴(kuò)展GtkSimpleLayout::Base即可,一個(gè)完整的例子:
?

require 'gtk2' require 'simple_layout'  class MyWin < Gtk::Window  include SimpleLayout::Base  def initialize   super   add my_layout   signal_connect('destroy') do    Gtk.main_quit   end  end   def my_layout   hbox do     label 'Hello, '     button 'World !'    end  end end 

?
MyWin.new.show_all?
Gtk.main??
?
20151214173039560.png (266×58)?
從上面的例子中可以看出,GtkSimpleLayout并沒(méi)有改變RubyGnome2程序的主框架,它只是一個(gè)擴(kuò)充。
?
?
屬性設(shè)置
在放置UI元件的時(shí)候,往往需要設(shè)置初始屬性,或者要指定布局參數(shù)。GtkSimpleLayout用Hash來(lái)傳遞這些屬性與參數(shù),例如:
?

vbox do  button 'sensitive = false', :sensitive => false # 初始為disable狀態(tài)  button 'expand space', :layout => [true, true] # 指定這個(gè)button填充剩余空間 end 

20151214173108985.png (437×62)

上面這個(gè)例子中,第一個(gè)button的初始狀態(tài)為disable。 ":sensitive => false"這個(gè)參數(shù)最終被轉(zhuǎn)換成屬性設(shè)置:Gtk::Button#sensitive=false,至于Gtk::Button有那些屬性可以設(shè)置,請(qǐng)參閱RubyGnome2 API文檔或GTK文檔。GtkSimpleLayout在這里只是作一個(gè)簡(jiǎn)單參數(shù)的轉(zhuǎn)換而已。
?
第二個(gè)button的":layout => [true, true]"有點(diǎn)特殊。":layout" 參數(shù)是GtkSimpleLayout的保留參數(shù),它會(huì)被轉(zhuǎn)換成當(dāng)這個(gè)UI被放入容器時(shí)候的參數(shù)。這個(gè)例子中,容器是vbox(Gtk::VBox),默認(rèn)的加入方法是Gtk::VBox#pack_start,這個(gè)例子中的[true, true] 最終會(huì)被傳遞到pack_start,因此這個(gè)button在被加入vbox的時(shí)候調(diào)用的方法以及參數(shù)是:"Gtk::VBox#pack_start( button, true, true)"。
?
因此,要使用GtkSimpleLayout,就首先要熟悉RubyGnome2的各個(gè)元件,容器的用法,以及參數(shù)。當(dāng)你熟悉了RubyGnome2以后,用GtkSimpleLayout就會(huì)非常簡(jiǎn)單。
?
批量屬性設(shè)置
在UI布局的時(shí)候,經(jīng)常碰到要對(duì)一組UI元件設(shè)置相同的屬性的情況,例如:

hbox do   button 'C', :layout => [false, false, 5]   button 'D', :layout => [false, false, 5]   button 'E', :layout => [false, false, 5] end 

20151214173136286.png (238×58)

這個(gè)時(shí)候,可以用"with_attr"來(lái)簡(jiǎn)化:

hbox do  with_attr :layout => [false, false, 5] do   button 'C'   button 'D'   button 'E'  end end  

?
特殊容器
有些容器的放置子元件的時(shí)候有 特殊要求,例如Gtk::HPaned,左邊子窗口要用Gtk::HPaned#add1()來(lái)添加,右邊的用Gtk::HPaned#add2()。對(duì)于這種容器,GtkSimpleLayout要特別對(duì)待,就以hpaned為例:

hpaned do  area_first do   frame 'first area'  end  area_second do   frame 'second area'  end end

? 20151214173231646.png (211×143)

需要特殊對(duì)待的容器有:
hpaned/vpaned : 用area_first和area_second來(lái)添加子窗口。
table : 用grid來(lái)填充格子。
nodebook : 用page來(lái)添加子頁(yè)。
?
標(biāo)識(shí)UI元件
GtkSimpleLayout用":id => ??"這個(gè)參數(shù)為UI元件進(jìn)行標(biāo)識(shí),例如:

hbox do  button 'first', :id => :btn_first  button 'second', :id => :btn_second end 

?
之后,可以用component()函數(shù)取得這個(gè)UI元件:

my_first_button = component(:btn_first) my_second_button = component(:btn_second)  ... my_first_button.signal_connect('clicked') do  puts "first button clicked" end  my_second_button.signal_connect('clicked') do  puts "second button clicked" end 

?
?
如果嫌麻煩,GtkSimpleLayout還提供了expose_components()用于自動(dòng)將所有已標(biāo)識(shí)的元件添加為實(shí)例讀屬性(getter):

expose_components() # 將自動(dòng)添加btn_first和btn_second這兩個(gè)讀屬性(getter)。??

... btn_first.signal_connect('clicked') do  puts "first button clicked" end  btn_second.signal_connect('clicked') do  puts "second button clicked" end 

?
?
自動(dòng)事件響應(yīng)映射
如果你嫌顯式調(diào)用signal_connect來(lái)注冊(cè)事件麻煩,那么GtkSimpleLayout為你提供了自動(dòng)事件響應(yīng)映射的功能:

require 'gtk2' require 'simple_layout'  class MyWin < Gtk::Window  include SimpleLayout::Base  def initialize   super   add my_layout   register_auto_events() # 注冊(cè)自動(dòng)事件響應(yīng)映射  end   def my_layout   hbox do    button "First', :btn_first    button "Second", :btn_second   end  end   # 事件響應(yīng)函數(shù)  def btn_first_on_clicked(*_)   puts "First button clicked"  end   # 事件響應(yīng)函數(shù)  def btn_second_on_clicked(*_)   puts "Second button clicked"  end   # 退出事件響應(yīng)函數(shù)  def self_on_destroy(*_)   Gtk.main_quit  end end 

?
最后那個(gè)'self‘是指宿主容器。
?
UI分組
有時(shí)候你希望對(duì)UI元件進(jìn)行分組,這樣就可以對(duì)同一組的UI元件進(jìn)行控制,如使能或禁止整個(gè)組。GtkSimpleLayout允許你在布局的時(shí)候指定UI組。
GtkSimpleLayout的UI分組規(guī)則如下:
默認(rèn)情況下,已命名的容器(即傳入了:id參數(shù))自動(dòng)對(duì)自己所屬的子元件建立一個(gè)組,組名就是容器明。
如果容器傳入:gid=>??參數(shù),則以此名稱(chēng)為所屬子元件建立組。
允許多個(gè)容器的:gid名字相同,這種情況下所屬子元件將歸為同一個(gè)組。
可以用“group”來(lái)顯式對(duì)UI分組,group可以看作是一個(gè)虛擬的容器。
用component_children(group_name)來(lái)獲取UI組。
?
由于UI分組的例子比較長(zhǎng)不在此列出,請(qǐng)參閱源碼中的examples/group.rb文件
?
?
UI與邏輯代碼分離
由于GtkSimpleLayout潛在地迫使使用者分離界面代碼和邏輯處理(或事件響應(yīng))代碼,使得整個(gè)程序的層次結(jié)構(gòu)更加清晰。對(duì)于界面元件比較多的程序,可以很方便的分區(qū)進(jìn)行l(wèi)ayout,因?yàn)閘ayout的結(jié)果還是容器,這個(gè)容器又可以放入其他容器組合成更復(fù)雜的界面。
?
由于GtkSimpleLayout并不改變RubyGnome2的程序結(jié)構(gòu),你可以選擇在你的程序中部分或全部使用GtkSimpleLayout。雖然本文所提供的例子都是靜態(tài)布局,但由于GtkSimpleLayout是存代碼構(gòu)建UI,因此你完全可以在布局的時(shí)候傳入變量,進(jìn)行動(dòng)態(tài)布局和動(dòng)態(tài)生成UI,而仍然保持UI代碼的“可視化”。
?
?
有興趣者可以看看GtkSimpleLayout實(shí)現(xiàn)的代碼,不過(guò)300行而已,這就是Ruby的魅力。
?
最后,貼上一個(gè)計(jì)算器的界面部分的代碼例子,你能從代碼中看出UI布局么?

require 'gtk2' require 'simple_layout'  class MyWin < Gtk::Window  include SimpleLayout::Base  def initialize   super   add my_layout   signal_connect('destroy') do    Gtk.main_quit   end  end   def my_layout   vbox do    with_attr :border_width => 3 do     hbox do      entry :id => :ent_input, :layout => [true, true, 5]     end     hbox do      frame do       label 'M', :set_size_request => [20, 20]      end      hbutton_box do       button 'Backspace'       button 'CE'       button 'C'      end     end     hbox do      vbutton_box do       button 'MC'       button 'MR'       button 'MS'       button 'M+'      end      with_attr :layout => [true, true] do       number_and_operators_layout      end     end    end   end  end   def number_and_operators_layout   vbox do    [ ['7', '8', '9', '/', 'sqt'],     ['4', '5', '6', '*', '%'],     ['1', '2', '3', '-', '1/x'],     ['0', '+/=', '.', '+', '=']].each do |cols|     hbox :layout => [true, true] do      cols.each do |txt|       button txt, :set_size_request => [20, 20], :layout => [true, true]      end     end    end   end  end  end 

?
MyWin.new.show_all?
Gtk.main?

20151214173350854.png (307×219)

Enjoy it :-)

以上就是進(jìn)行GTK之Ruby GUI編程的基本方法,相信現(xiàn)在大家都有了更加清晰的了解了吧?如果你還想了解更多的知識(shí),建議你來(lái)武林技術(shù)頻道網(wǎng)站學(xué)習(xí)吧。

發(fā)表評(píng)論 共有條評(píng)論
用戶(hù)名: 密碼:
驗(yàn)證碼: 匿名發(fā)表

圖片精選

主站蜘蛛池模板: 免费观看一区 | 久久精品探花 | 国产88久久久国产精品免费二区 | 黄视频在线网站 | 精国产品一区二区三区 | 性高跟鞋xxxxhd4kvideos | 国产日韩线路一线路二 | 久久久久国产成人精品亚洲午夜 | 亚洲第一色婷婷 | 欧美一区二区三区中文字幕 | 亚洲精品一区二区三区免 | 久草经典视频 | 九九热在线观看视频 | 午夜男人在线观看 | 成年免费观看视频 | 视频一区国产 | 日韩视频在线视频 | 欧美日本色 | 国产乱淫av片免费观看 | qyl在线视频精品免费观看 | 中文在线国产 | 久久亚洲精品11p | 国产一级免费av | 亚洲综合一区在线观看 | 深夜免费视频 | xxxx18韩国护士hd老师 | 国产无限资源在线观看 | 欧美成人亚洲 | 一级免费特黄视频 | 免费黄色小视频网站 | 久久久久久久爱 | 久久看免费视频 | 精品国产一区二区三 | 日韩精品中文字幕一区二区三区 | 神秘电影91| 久草视频福利在线观看 | 国内精品久久久久久久久久 | 日本羞羞的午夜电视剧 | 日韩中文字幕三区 | 91情侣偷在线精品国产 | 国产精品久久久久久久久久尿 |