ruby tk实现简易计算器

#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

 

posted @ 2019-07-10 20:00  SHHHS  阅读(400)  评论(0编辑  收藏  举报