Glade3&Ruby&GtkBuilder小示例

这篇文章主要内容:首先通过Glade3的GtkBuilder引擎设计好程序的GTK界面,然后在Ruby代码中调用这个glade文件来进行GTK+程序设计,最終結果是个小小的计算器。

calculate-of-abito-linpie-com
右边那个就是最終效果图,样子还算不错。

ABitNo开始啰嗦,不喜欢啰嗦的可以直接到后面看代码

其实事情是由于ABitNo这两天给自己放假休息,今天下午醒来后发现没什么东西要做就写了这么个东西。代码很简陋,不过功能考虑的还算是周全的,异常也应该都处理了,到最后看一下代码就几十行,Ruby果然是对Programmer相当友好。

如果用C或者Java什么的来写的话,不考虑界面因素,代码也会多出不止几十行来。如果有牛人欢迎来鄙视我,教育ABitNo一下。

这仅仅是ABitNo自己的一个简单学习过程而已,另外还可以看一下ABitNo之前写的C语言Glade3和GTK编程的入门文档http://abitno.linpie.com/glade-3-gtk-2-begin.html
Ruby和GTK程序设计教程http://www.zetcode.com/tutorials/rubygtktutorial/
GTK+程序设计教程http://www.zetcode.com/tutorials/gtktutorial/

下面列出的是Ruby文件代码

#!/usr/bin/ruby
$KCODE = "U"
require 'gtk2'

class Calculate

  def initialize
    Gtk.init

    @builder = Gtk::Builder.new
    @builder.add_from_file('calculate.glade')

    @window = @builder.get_object('window')
    @window.signal_connect("destroy") { Gtk.main_quit }

    @entry = @builder.get_object('entry')

    get_button_exe_cmd('button_result') do
      @entry.text = calculate(@entry.text).to_s
    end

    get_button_exe_cmd('button_clear') do
      @entry.text = '0'
    end

    get_button_exe_cmd('button_backspace') do
      @entry.text = @entry.text.chop
    end

    @builder.objects.each do |o|
      o.signal_connect('clicked') {
        @entry.text=@entry.text == '0' ? o.label : @entry.text<< o.label
      } if((o != @button_result) &&
          (o != @button_clear) &&
          (o != @button_backspace) &&
          (o.kind_of? Gtk::Button))
    end

    @window.show_all
    Gtk.main
  end

  private
  class Stack
    def initialize
      @arr = []
    end

    def push(x)
      @arr << x
    end

    def pop
      @arr.shift
    end

    def empty?
      @arr.empty?
    end
  end

  def check_parentheses(str)
    stack = Stack.new
    str.each_char do |chr|
      stack.push(chr) if chr == '('
      if chr == ')'
        return false if stack.empty?
        stack.pop
      end
    end
    stack.empty?
  end

  def calculate(str)
    num = /[+-]?\d+(\.\d+)?(e[+-]?\d+)?/
    reg = /^#{num}([*+-\/]#{num})*$/

    if(check_parentheses(str) && (str.gsub(/\(|\)/,'') =~ reg))
      str.gsub!(/\/\d+(?!\.)/, '\0' << '.0')
      eval(str.strip)
    else
      'Invalid expression'
    end
  rescue Exception => err
    puts err
    'Unknown Exception'
  end

  def get_button_exe_cmd(name, &cmd)
    button = @builder.get_object(name)
    button.signal_connect('clicked', &cmd)
    instance_variable_set("@"<<name, button)
  end
end

Calculate.new

如果某个人要学习Ruby的GTK编程,那这个人就一般不会是刚学编程的,不知道这种感觉对不对,似乎没有哪个人是从Ruby开始学编程的吧。所以呢,就直接把代码给列出来了,没有写注释,主要是ABitNo实在很懒。

不过还是要说一下其中的一些问题,我首先是用一个简单的Stack来保证括号没有匹配错误,然后用一个正则表达式保证输入的是合法的算式,不过这个Reg有个问题我不明白,就是像6.8.9这样的数字竟然过滤不掉,但是我如果直接把num那个表达式写入到reg里的话就不会出这个问题,希望有人指教。

至于Glade方面,是用的GtkBuilder,而不是已经过时的Libglade格式,google了一下没发现关于Ruby和GtkBuilder方面的资料,所以才想写这篇文章的。

那个用来进行信号处理的get_button_exe_cmd方法主要是为了保证代码的简洁硬抽出来的,发现也没简化什么东西。。。

不多说了,有人愿意学习可以用glade按照上面的样式设计个界面,把部件的name写对就成了。。。

明天回家,9月再回来。。。

9 COMMENTS >>LEAVE<<

  1. kangzj

    这个不大懂
    又回家,真幸福啊

  2. tmdab123


    Python+GTK

    嘿嘿……

  3. 黑煞哥

    开学咯,一起 加油咯! 好好干一场咯, 我也加油的。

  4. HicroKee

    其实我想说,做计算器的难度在于处理表达式、了解编译原理。用eval+re当然快,但就没难度了可言~

  5. ABitNo
    @HicroKee

    这个我完全明白。。。不过我可不想做个计算器,只是拿来介绍下Glade3和Ruby的简单入门而已。。。

  6. ABitNo
    @黑煞哥

    我也开学了。。。加油。。。

  7. ABitNo
    @kangzj

    幸福了。。。我又回来了,从我出家门到学校门口总共用时4.5小时

  8. ABitNo
    @tmdab123

    我不管了,以后写桌面程序我就用C,写web用ruby

  9. SorryDreams

    ruby果然够简单够强大。

LEAVE A RESPONSE >>CANCEL<<

loader