今天逛InfoQ 的时候居然发现了Shoes,一个Ruby GUI 客户端。试了一下,比Ruby/Tk 好用。比如这个Tutorial 里面的例子。假设下面的代码保存在background.rb 里面。
- Shoes.app do
- background "#F3F".."#F90"
- title "Shoooes", :top => 60,
- :align => "center",
- :font => "Trebuchet MS",
- :stroke => white
- end
安装Shoes 之后,用Shoes 打开这个.rb 文件就可以看到:
可能是由于刚出现的原因,响应还很慢(有人用"两百来行"编了个扫雷,鼠标点下去半天没反应)。但我相信它会引起又一轮Ruby 浪潮。
Shoes 并不是针对严谨的大规模GUI 应用,Shoes 应用一般都很灵巧。Shoes 的目标是让GUI 编程愉快、有趣。
Shoes 有本漫画教程NOBODY KNOWS SHOES,是why 大叔亲自写的。
一个GUI 应该包括显示和响应两方面元素。
Shoes 有10种元素用于显示:
para 是paragraph 的简写。你不必给它任何坐标或者尺寸参数。它会自动填充它所在的box。但可以为文本指定格式。比如:strong() 就是加粗,em() 是强调等。
- Shoes.app do
- para "Testing test test. ",
- strong("Breadsticks. "),
- em("Breadsticks. "),
- code("Breadsticks. "),
- strong(ins("Very good."))
- end
还可以指定字体大小:title 什么的或者直接指定(如:para "Oh, to fling and be flung.", :size => 48)
- Shoes.app do
- title "Title/n"
- subtitle "Subtitle/n"
- tagline "Tagline/n"
- caption "Caption/n"
- para "Para/n"
- inscription "Inscription/n"
- end
stack 和flow 就是Shoes 里面的布局管理器。stack 把部件垂直摞在一起。flow 也是一种容器,只不过它在水平方向上摆放部件。如果一行摆不下了,它会另起一行。主窗口本身也是一个flow。flow 和stack 组合可以形成不同的布局。如果你是一个Web 开发者,你会发现它们很像CSS布局引擎。也不奇怪,Shoes 的作者why the lucky stiff说他深受Web 开发的影响。比如:后面你会看到的Shoes 的一种虚拟部件link。
- Shoes.app do
- @o = oval :top => 0, :left => 0,
- :radius => 40
- stack :margin => 40 do
- title "Dancing With a Circle"
- subtitle "How graceful and round."
- end
- motion do |x, y|
- @o.move width - x, height - y
- end
- end
当鼠标移动时,motion 会拿到你鼠标的坐标重新绘制圆。
一旦你点击button,就会激活它之后的block。
- Shoes.app {
- button("Trurl?") {
- alert("Klapaucius!")
- }
- }
还可以这么写:
- Shoes.app {
- @b = button("Trurl?")
- @b.click { alert("Klapaucius!") }
- }
button 还有个方法focus()。如果用户敲了回车,按钮就会按下(手册上这么说,但我还没试成)。
图片可以是PNG, JPEG 或者GIF;可以从本地文件系统,也可以从Web 上载入。还可以通过:height 和:width调整图片大小。
- Shoes.app do
- image("f:/Ruby.jpg", :click=>"http://google.com")
- end
text 把敲进编辑框的内容当作字符串返回。
- Shoes.app do
- @e = edit_line :width => 400
- button "O.K." do
- alert @e.text
- end
- end
如果是多行,可以用edit-box。
- Shoes.app do
- @e = edit_box "Would that I...", :width => 400, :height => 240
- button "O.K." do
- alert @e.text
- end
- end
- link
- Shoes.app do
- para(link("Google", :click=>"http://google.com"))
- end
一幅背景包括三个要素:颜色、明暗变化和图片。你可以用内建的颜色,也可以用rgb 方法。查看这里。
- class BookList < Shoes
- url '/', :index
- url '/twain', :twain
- url '/kv', :vonnegut
- def index
- para "Books I've read: ",
- link("by Mark Twain/n", :click => "/twain"),
- link("by Kurt Vonnegut/n", :click => "/kv")
- end
- def twain
- para "Just Huck Finn./n",
- link("Go back.", :click => "/")
- end
- def vonnegut
- para "Cat's Cradle. Sirens of Titan. ",
- "Breakfast of Champions./n",
- link("Go back.", :click => "/")
- end
- end
- Shoes.app :width => 400, :height => 500
url 还可以是正则表达式:
- class Dictionary < Shoes
- url '/', :index
- url '/(/w+)', :word
- def index
- stack do
- title "Enter a Word"
- @word = edit_line
- button "OK" do
- visit "/#{@word.text}"
- end
- end
- end
- def word(string)
- stack do
- para "No definition found for #{string}. ",
- "Sorry this doesn't actually work."
- end
- end
- end
- Shoes.app
- clear
- Shoes.app {
- @poem = stack {
- para "
- My eyes have blinked again
- And I have just realized
- This upright world
- I have been in.
-
- My eyelids wipe
- My eyes hundreds of times
- Reseting and renovating
- The scenery."
- }
- para(link("Clear").
- click { @poem.clear })
- }
此外,Shoes 还提供了click,animate等。
- Shoes.app :width => 200, :height => 120 do
- @seconds = 0
- @paused = false
- def display_time
- @display.clear do
- title "%02d:%02d:%02d" % [
- @seconds / (60*60),
- @seconds / 60 % 60,
- @seconds % 60
- ], :stroke => @paused ? gray : black
- end
- end
- @display = stack :margin => 10
- display_time
- button "Pause", :width => '50%' do
- @paused = !@paused
- display_time
- end
-
- button "Reset", :width => '50%' do
- @seconds = 0
- display_time
- end
- animate(1) do
- @seconds += 1 unless @paused
- display_time
- end
- end
如果你感兴趣,应该去Shoebox 逛逛,N多牛人啊!