[#37021] [RAA] RAA/2.3 — "U.Nakamura" <usa@...>

みなさんこんにちは。

20 messages 2003/01/30

[ruby-list:36965] Re: Gtk.main

From: "TOYOFUKU Chikanobu" <toyofuku@...>
Date: 2003-01-18 17:16:03 UTC
List: ruby-list #36965
  豊福です。

少し前の話題ですが

私(豊福)
Date: Thu, 5 Dec 2002 15:14:43 +0900
[ruby-list:36671] Re: Gtk.main
>    Gtk.main と Gtk.main_quit とダイアログとスレッドがごっちゃ
> になって混乱しています。整理がついたら改めてフォローしたいと
> 思います。

についてやっと整理しました。

(a) Gtk.main はネストしてよい。
(b) ダイアログではボタンが押されるまで他の処理を待たせる
  ケースが多いがそのときには Gtk.main を使う。
(c) 制御が戻らない重い処理をしているときにウィンドウの再描画
  させるには別スレッドを作ってそこで Gtk.main相当の処理を
  させるしかない。
(d) Gtk.main_quit は一番内側の Gtk.main を抜けろと指示する。
(e) 別スレッドで実行されている Gtk.main にも Gtk.main_quit は
  効くようだ。

  最後の (e) は試してみた結果からの推測です。

>    やりたいことをさらに具体的にいうとまずウィンドウAを出し
> ていてそこにつけたメニューから重い処理を実行します。重い処理
> というのは外部コマンドを何回か system(正確には IO.popen)で
> 実行しています。そのときに「しばらくお待ちください」ダイアロ
> グを出しそのダイアログにはキャンセルボタンがついていてその
> ボタンでキャンセルすると重い処理を中断します。ダイアログの
> 移動でウィンドウAが expose されたときは再描画します。
> 重い処理が終了したら「しばらくお待ちください」ダイアログを
> 「終了しました」ダイアログにします。

  結局以下のようなコードにしました。

require 'gtk'

class MyDialog < Gtk::Dialog
  def initialize
    super
    set_modal(true)            
    @label = Gtk::Label.new('')
    vbox.pack_start @label
    @ok_button = Gtk::Button.new('OK')
    @ok_button.signal_connect(Gtk::Button::SIGNAL_CLICKED) do
      Gtk.main_quit
      hide
    end
    action_area.pack_start @ok_button

    @cancel_button = Gtk::Button.new('CANCEL');
    @cancel_button.signal_connect(Gtk::Button::SIGNAL_CLICKED) do
      print "cancel\n"
      $cancel = true
      @label.set_text('wait a moment'); @label.show
      @cancel_button.hide; @ok_button.hide
      show
    end
    action_area.pack_start(@cancel_button, true, true, 20) 
  end

  def wait
    @label.set_text('executing ...'); @label.show
    @ok_button.hide; @cancel_button.show
    show
    Gtk.main
  end

  def finish
    @label.set_text('finished'); @label.show
    @cancel_button.hide; @ok_button.show
    show
    Gtk.main
  end
end


button = Gtk::Button.new("start")
button.signal_connect(Gtk::Button::SIGNAL_CLICKED) do
  th = Thread.new { $dia.wait }
  $cancel = false
  (0..3).each { |i|
    break if ($cancel)
    print "sleep\n"
    sleep(5) # 重い処理
  }
  Gtk.main_quit
  th.join
  $dia.finish
end

$dia = MyDialog.new
win = Gtk::Window.new
win.add(button)
win.show_all
Gtk.main

---
                        豊福
                        ttoyofukujp@ybb.ne.jp


In This Thread

Prev Next