まずは使ってみよう
まずは ruby-gdcl を使って絵を描いてみよう
スクリーンショット
 
sample1.rb
-- sample1.rb ここから --
require "gtk"
require "narray"
require "numru/dcl"
require "numru/gdcl"
include NumRu
include Math
NMAX = 400
$pixmap = nil
def expose_event(widget, draw)
  if ! $pixmap.nil?
    area = draw.area
    gc = widget.style.fg_gc(widget.state)
    widget.window.draw_pixmap(gc, $pixmap, area.x, area.y,
			     area.x, area.y, area.width, area.height)
  end
  false
end
def configure_event(widget)
  geom = widget.window.get_geometry
  if (geom[2]>0 && geom[3]>0) then
    $pixmap = Gdk::Pixmap.new(widget.window, geom[2], geom[3], -1)
    $pixmap.draw_rectangle(widget.style.white_gc, true, 0, 0, 
			  geom[2], geom[3])
  end
  GDCL::zgsdrw(widget)
  DCL::sgopn(4)
  GDCL::zgspmp($pixmap)
  draw_graph
  true
end
def draw_graph
  x = NArray.new(NArray::FLOAT, NMAX)
  y = NArray.new(NArray::FLOAT, NMAX)
  dt = 2.*3.14159/(NMAX-1)
  for n in 0..NMAX-1
    t = dt*n
    x[n]=100. * sin(4.*t)
    y[n]=0.001*cos(5.*t) + 6.0
  end
  DCL::grfrm
  DCL::ussttl("X-TITLE", "x-unit", "Y-TITLE", "y-unit")
  DCL::usgrph(NMAX, x, y)
end
draw_area = Gtk::DrawingArea.new
draw_area.signal_connect("expose_event"){|w,p| expose_event(w,p)}
draw_area.signal_connect("configure_event"){|w,p| configure_event(w)}
draw_area.show
window = Gtk::Window.new(Gtk::WINDOW_TOPLEVEL)
window.set_title("sample1.rb")
window.add(draw_area)
window.show
Gtk::main
-- sample1.rb ここまで --
解説
     require "gtk"
     require "narray"
     require "numru/dcl"
     require "numru/gdcl"
     include NumRu
     include Math
     
     include すると NumRu::DCL を DCL とかける
 定数及び初期値を設定する
     
     NMAX = 400
     $pixmap = nil
     
 $pixmap を widget(=draw_area) にコピーする
     
     def expose_event(widget, draw)
       if ! $pixmap.nil?
         area = draw.area
         gc = widget.style.fg_gc(widget.state)
         widget.window.draw_pixmap(gc, $pixmap, area.x, area.y,
         area.x, area.y, area.width, area.height)
       end
       false
     end
     
     引数として
     widget に draw_area が、draw に Gdk::EventExpose が渡される
 widget(=draw_area) の大きさに合わせた $pixmap を作り、
     DCL を open し、 draw_greph を呼び出す
     
     def configure_event(widget)
       geom = widget.window.get_geometry
       if (geom[2]>0 && geom[3]>0) then
         $pixmap = Gdk::Pixmap.new(widget.window, geom[2], geom[3], -1)
	 $pixmap.draw_rectangle(widget.style.white_gc, true, 0, 0, geom[2], geom[3])
       end
       GDCL::zgsdrw(widget)
       DCL::sgopn(4)
       GDCL::zgspmp($pixmap)
       draw_graph
       true
     end
     
     引数として widget に draw_area が渡される
     Gtk+ を利用するときは iws=4 を指定する
 DCL で $pixmap に対し描画する
     
     def draw_graph
       x = NArray.new(NArray::FLOAT, NMAX)
       y = NArray.new(NArray::FLOAT, NMAX)
       dt = 2.*3.14159/(NMAX-1)
       for n in 0..NMAX-1
       t = dt*n
       x[n]=100. * sin(4.*t)
       y[n]=0.001*cos(5.*t) + 6.0
       end
       DCL::grfrm
       DCL::ussttl("X-TITLE", "x-unit", "Y-TITLE", "y-unit")
       DCL::usgrph(NMAX, x, y)
     end
     
 Gtk::Drawing_area を用意し、
     "expose_event","configure_event" イベントが発生するとそれぞれ
     expose_event(w,p),configure_event(w,p) を呼び出す
     
     draw_area = Gtk::DrawingArea.new
     draw_area.signal_connect("expose_event"){|w,p| expose_event(w,p)}
     draw_area.signal_connect("configure_event"){|w,p| configure_event(w)}
     draw_area.show
     
 Gtk::Window を用意し、タイトルを設定し、draw_area をつける
     
     window = Gtk::Window.new(Gtk::WINDOW_TOPLEVEL)
     window.set_title("sample1.rb")
     window.add(draw_area)
     window.show
     
 メインのループ
     
     Gtk::main
     
主な変数及びイベント
変数
| window: | メインの窓 | 
| $pixmap: | 実際にDCLが描画するもの(見えない) | 
| draw_area: | $pixmapをコピーすることによって描画が行われる領域(見える) | 
イベント
| "configure_event": | はじめに描画するときや、サイズが変更されたときに生じる | 
| "expose_event": | configure_eventの後や、隠れていた窓が現れたときなどに生じる | 
とりあえず絵が描けたはず。
窓のサイズを大きくすれば絵のサイズも変わる。
生DCLではマウスでクリックしたりいくつかのキーを押すと終了した。
しかしsample1.rbでは終了しない。
またウインドウマネージャーの機能で窓を消す(たとえば右上の×印を押す)と
確かに窓は消えるがループは続いており、プロンプトが返ってこないはずだ。
^C(Ctrl-C)で止めよう。
Gtk+では様々なイベントに対する処理を自分で設定できる反面、
基本的にすべてのイベントに対する応答を記述してやらなければならない。
次へ
go back