07

22

[Ruby] ThreadからGUIに画像を表示する / 外部のThreadから指定されたタイミングでRuby/Tkに画像を表示する

2012.07.22(21:53)

GUIシステムは自分でイベントドリブンのしくみを持ち、自分がわかっているマウス操作やキー入力に対する再描画のしくみを実現することができる。しかし実行中はイベントドリブンを全力で実行しているため、自分が決めた好きなタイミングで再描画できるようにするには一工夫が必要だ。

外部のThreadから、自分が決めた好きなタイミングでRuby/Tkに画像を表示するサンプルを作ってみた。

# coding: windows-31j
# Ruby1.9.3版

# image_frame.rb
# Tk,拡張Tkが必要。
require "tk"
require "tkextlib/tkimg/png"
require "tkextlib/tkimg/jpeg"

class ImageFrame

  def start
    $image = TkPhotoImage.new("file" => "empty.gif")
    $name = self.class.name
    TkRoot.new{ |r|
      r.title($name)
      TkCanvas.new { |c|
        width 600
        height 200
        bg 'gray'
        $tkc_image = TkcImage.new(c, width/2, height/2, "image" => $image)
        pack
      }
      $tk_label = TkLabel.new(r) {
        width 600
        height 200
        bg 'white'
        image $image
        pack
      }
    }
    Tk.mainloop
  end

  def draw_image(image_file)
    image = TkPhotoImage.new("file" => image_file)
    $tkc_image.configure("image" => image)
    $tk_label.image = image
    printf "draw_image #{image_file}\n"
  end

end

if __FILE__ == $0
  image_frame = ImageFrame.new
  t1 = Thread.new(image_frame) { |image_frame|
    image_frame.start
  }
  2.times {
    sleep 1
    image_frame.draw_image("ruby.gif")
    sleep 1
    image_frame.draw_image("ruby.png")
    sleep 1
    image_frame.draw_image("ruby.jpg")
    sleep 1
  }
  printf "close #{image_frame.class.name}\n"
  t1.join
  printf "fine\n"
end

TkCanvasの上に載っているTkcImageを再描画するのと、TkLabelのimageを再描画するのとやり方が違うので、同じ画像を2箇所に表示するサンプルとした。

ImageFrameクラスがRuby/Tkのイベントループを実現し、Tk.mainloopを実行すると全力でイベントループを実行し、他のことをやる余裕はなくなる。

そのため、ImageFrameクラスに外部から呼び出せる draw_imageメソッドを用意し、その中から、2箇所に対して再描画するために必要な処理を呼び出す。

一方、メインでは、sleepしながら、ImageFrameクラスに対して draw_imageを呼び出す。このようにすることで自分が決めたタイミングで、再描画させることができるようになる。

同様のことをJavaでやってみた。

Javaの場合
[Java] ThreadからGUIに画像を表示する / 外部のThreadから指定されたタイミングでJava Swing JFrameに画像を表示する
http://saltheads.blog134.fc2.com/blog-entry-74.html

プロフィール

島敏博

Shima Toshihiro 島敏博
信州アルプスハイランド在住。HaskellとElixirが好き。組み込みソフトウェアアーキテクト、C++プログラマ、山歩き、美術館巡り、和食食べ歩き、日本赤十字社救急法指導員、インデックス投資、クラシック音楽、SESSAME会員、状態マシン設計、モデル駆動開発、ソフトウェアプロダクトライン、Rubyist、実践ビジネス英語

■ ツイッター
http://twitter.com/saltheads
■ Facebook
http://www.facebook.com/saltheads
■ Qiita
http://qiita.com/saltheads

印刷する場合は、ブラウザの印刷メニューではなく、このページの上から3cmくらいの青いところにある、「印刷」を押してみてください。少しうまく印刷できます。まだ完全ではないのですが、これで勘弁してください。


カテゴリ
最新記事
月別アーカイブ
最新コメント
検索フォーム
リンク
sessame
RSSリンクの表示