#encding:GBK require 'tk' module Const WIDTH_OF_PANEL = 370 HEIGHT_OF_PANEL = 520 SIZE_OF_BUTTON_H = 60 SIZE_OF_BUTTON_W = 80 HEIGHT_OF_DISPLAY_FRAME = 90 HEIGHT_OF_VALUE_LABEL = 30 HEIGHT_OF_OPERATION_LABEL = 20 BORDER_WIDTH = 2 PADX = 10 PADY = 10 OP_ARRAY = ["%","sqrt","x^2","1/x","CE","C","DEL","/","7","8","9","*","4","5","6","-","1","2","3","+","+/-","0",".","="] end include Const $value_tk_var = TkVariable.new(0) $operate_tk_var = TkVariable.new $Font = TkFont.new('arial 18') class ButtonInfor attr_accessor :x, :y protected :x=, :y= def initialize(x=0,y=0) @x , @y = x , y end end module Work def number(num) if $value_tk_var.value == "0" $value_tk_var.value = num elsif $value_tk_var.value == '-0' $value_tk_var.value = $value_tk_var.value.chop + num puts "bbbb" elsif $value_tk_var.value != "0" $value_tk_var.value += num end end def point unless /\./ =~ $value_tk_var.value $value_tk_var.value += "." end end def calcu( key ) unless (/\+/ =~ $operate_tk_var.value || /-/ =~ $operate_tk_var.value || /\*/ =~ $operate_tk_var.value || /\// =~ $operate_tk_var.value) $operate_tk_var.value = $value_tk_var.value + " " + key $value_tk_var.value = 0 else $operate_tk_var.value = $operate_tk_var.value.chop + key end end def equl operator_ = $operate_tk_var.value[$operate_tk_var.value.size-1] $operate_tk_var.value = $operate_tk_var.value.chop num2 = (/\./ =~ $value_tk_var.value) ? $value_tk_var.value.to_f : $value_tk_var.value.to_i num1 = (/\./ =~ $operate_tk_var.value) ? $operate_tk_var.value.to_f : $operate_tk_var.value.to_i case operator_ when "+" $value_tk_var.value = ( num1 + num2 ).to_s when "-" $value_tk_var.value = ( num1 - num2 ).to_s when "*" $value_tk_var.value = ( num1 * num2 ).to_s when "/" if num2 == 0 || num2 == 0.0 $value_tk_var.value = "CANNOT DEVIDED BY 0!" else $value_tk_var.value = ( num1 / num2 ).to_s end end $operate_tk_var.value = nil end def clear(op) $value_tk_var.value = 0 $operate_tk_var.value = nil if (op == "C") end def del $value_tk_var.value = $value_tk_var.value.chop end def sqrt_ $value_tk_var.value = Math.sqrt($value_tk_var.value.to_f) end def sq_ $value_tk_var.value = $value_tk_var.value.to_f * $value_tk_var.value.to_f end def devide_one $value_tk_var.value = 1/($value_tk_var.value.to_f) end def negate if $value_tk_var.value[0] != '-' $value_tk_var.value = "-" + $value_tk_var.value else $value_tk_var.value = $value_tk_var.value.reverse.chop.reverse end end def get_pos_hash tmp = Hash.new (0..23).each do |i| tmp[OP_ARRAY[i]]=ButtonInfor.new((i%4)*(PADX+SIZE_OF_BUTTON_W),(i/4)*(PADY+SIZE_OF_BUTTON_H)) end return tmp end module_function :number , :point , :clear , :calcu , :equl , :del , :sqrt_ , :sq_ , :devide_one , :get_pos_hash ,:negate end #创建主窗口 root = TkRoot.new do title "SHH's Calculator"; geometry WIDTH_OF_PANEL.to_s + "x" + HEIGHT_OF_PANEL.to_s; end operat_frame = TkFrame.new do relief 'groove' pack('fill' => 'x') borderwidth BORDER_WIDTH padx PADX pady PADY place:'height' => HEIGHT_OF_PANEL-HEIGHT_OF_DISPLAY_FRAME , 'width' => WIDTH_OF_PANEL , 'x' => 0 , 'y' => HEIGHT_OF_DISPLAY_FRAME background "LightCyan" end display_frame = TkFrame.new do relief 'groove' pack('fill' => 'x') borderwidth BORDER_WIDTH padx PADX pady PADY place:'height' => HEIGHT_OF_DISPLAY_FRAME , 'width' => WIDTH_OF_PANEL , 'x' => 0 , 'y' => 0 background "lightblue" end value_label = TkLabel.new(display_frame) do relief 'groove' pack('fill' => 'x') borderwidth BORDER_WIDTH textvariable font $Font place:'height' => HEIGHT_OF_VALUE_LABEL , 'width' => WIDTH_OF_PANEL - PADX * 2 , 'x' => 0 , 'y' => 0 end operation_label = TkLabel.new(display_frame) do relief 'groove' pack('fill' => 'x') borderwidth BORDER_WIDTH textvariable font TkFont.new('arial 10') place:'height' => HEIGHT_OF_OPERATION_LABEL , 'width' => WIDTH_OF_PANEL * 0.618 , 'x' => WIDTH_OF_PANEL * (1-0.618) - PADX * 2 , 'y' => HEIGHT_OF_VALUE_LABEL + PADY end value_label['textvariable'] = $value_tk_var operation_label['textvariable'] = $operate_tk_var Work.get_pos_hash().each do |key,value| TkButton.new(operat_frame) do font "Consolas 15" place:'height' => SIZE_OF_BUTTON_H , 'width' => SIZE_OF_BUTTON_W , 'x' => value.x , 'y' => value.y text key background (("0".."9") === key)? "Gainsboro" : "Gray" command do case key when ("0".."9") Work.number(key) when "." Work.point() when "+","-","*","/" Work.calcu(key) when "=" Work.equl() when "CE","C" Work.clear(key) when "DEL" Work.del() when "sqrt" Work.sqrt_() when "x^2" Work.sq_() when "1/x" Work.devide_one() when "+/-" Work.negate() end end end end Tk.mainloop