GUI で電卓なんて簡単にできるだろうと思ったら大間違いでした。
Ruby コード。
dentaku.rb
require 'gtk2' class Calculator def initialize(entry) @entry = entry clear end def input(n) a = ["AC", "C" , "√", "**", 7, 8, 9, "+", 4, 5, 6, "-", 1, 2, 3, "*", 0, ".", "=", "/"][n] parse(a) end def show(st) @entry.set_text(st) end def clear @buffer = [] @left = "" @operator = nil show("") end def parse(c) case c when "AC" clear when "C" return if @buffer.empty? @buffer = [] show("") when 0..9, "." if /^0/.match(number) and !/^0\./.match(number) @buffer = @buffer.drop_while {|x| x == 0} end if @buffer.empty? and c == "." @buffer = [0, "."] elsif @buffer.count(".").zero? or c != "." @buffer << c end show(number) when "*", "/", "+", "-", "**", "=" right = eval(number).to_s return if right.empty? and !@operator and @left.empty? #最初であるとき @buffer = [] if @operator and !right.empty? begin right = eval(@left + @operator + right).to_s raise ZeroDivisionError if right == "Infinity" show(right) rescue ZeroDivisionError clear show("ZeroDivisionError") return end end @left = right unless right.empty? @operator = (c == "=") ? nil : c when "√" st = eval(number).to_s @buffer = [] if !st.empty? @left = eval("Math.sqrt(#{st})").to_s elsif !@left.empty? @left = eval("Math.sqrt(#{@left})").to_s else return end show(@left) else raise "error" end end def number @buffer.join end end class MainWindow < Gtk::Window def initialize super("電卓") set_resizable(false) entry = Gtk::Entry.new entry.set_editable(false) entry.set_xalign(1) #右詰め entry.set_height_request(40) entry.modify_font(Pango::FontDescription.new("12")) #フォントのサイズ @calc = Calculator.new(entry) box = Gtk::VBox.new add(box) box.pack_start(entry, false, true, 0) box.pack_start(buttons_area, true, true, 0) signal_connect("destroy") {Gtk.main_quit} show_all end def buttons_area characters = %W(AC C √ ^ 7 8 9 + 4 5 6 - 1 2 3 × 0 . = ÷) hboxes = Array.new(5) {Gtk::HBox.new} i = 0 area = Gtk::VBox.new hboxes.each do |box| 4.times do b = Gtk::Button.new b.set_size_request(50, 40) l = Gtk::Label.new(characters[i]) l.modify_font(Pango::FontDescription.new("12")) b.add(l) n = i b.signal_connect("clicked") {@calc.input(n)} box.pack_start(b, true, true, 0) i += 1 end area.pack_start(box, true, true, 0) end area end end MainWindow.new Gtk.main
GUI の部分は簡単でしたが、電卓のボタン処理をする部分(parse()
メソッド)がぐちゃぐちゃになってしまいました。明らかにクソコードですね(^^;
ぐぐってみると普通の電卓を GUI でエミュレートしたような実装例はなかなかないですね。少なくとも Ruby では見つけられませんでした。Ruby でいうと簡易 irb みたいなのを実装する話が多いです。