[#47364] nokogiri-1.4.3.1のBus Errorについて — Tomohiko Hayashi <hayashi-t@...>
こんにちは!
6 messages
2010/09/04
[#47369] cgiのパラメータについて — nonta <nonta@...>
野田と申します。
9 messages
2010/09/06
[#47391] ruby-1.9.2 で Net::Telnet の close ができない — HAMANO Kiyoto <kiyoto@...>
濱野と申します。
9 messages
2010/09/10
[#47392] Re: ruby-1.9.2 で Net::Telnet の close ができない
— Kazuhiro NISHIYAMA <zn@...>
2010/09/10
西山和広です。
[#47404] Re: ruby-1.9.2 で Net::Telnet の close ができない
— HAMANO Kiyoto <kiyoto@...>
2010/09/13
西山さん、
[#47408] Re: ruby-1.9.2 で Net::Telnet の close ができない
— Kazuhiro NISHIYAMA <zn@...>
2010/09/15
西山和広です。
[#47396] Rubytterとスレッドについて — "Jun'ya Shimoda" <jun-shimo@...>
下田と申します。
5 messages
2010/09/11
[#47413] undefined symbol: rb_eThreadErrorについて — Shusaku Yokota <blueberrycandle@...>
はじめまして、†しゅう†といいます。
8 messages
2010/09/16
[#47421] Re: undefined symbol: rb_eThreadErrorについて
— Tsutomu Kotake <t-kotake@...>
2010/09/17
こたけと申します。
[#47414] <=>の意味は? — "T.Soejima" <clev@...2.so-net.ne.jp>
そえじま@勉強中です。
37 messages
2010/09/17
[#47420] Re: <=>の意味は?
— 藤川浩明 <fhir0aki3@...>
2010/09/17
他の方がすでに解答されているみたいですが、一応僕なりの答えを書いてみます。僕もRuby初心者なのではっきりとは言えないんですが・・・。
[#47422] Re: <=>の意味は?
— "T.Soejima" <clev@...2.so-net.ne.jp>
2010/09/17
そえじま@勉強中です。
[#47424] Re: <=>の意味は?
— "Y. NOBUOKA" <nobuoka@...>
2010/09/17
信岡です。
[#47426] Re: <=>の意味は?
— "T.Soejima" <clev@...2.so-net.ne.jp>
2010/09/17
そえじま@勉強中です。
[#47428] Re: <=>の意味は?
— "Y. NOBUOKA" <nobuoka@...>
2010/09/17
そえじまさん
[#47429] Re: <=>の意味は?
— "T.Soejima" <clev@...2.so-net.ne.jp>
2010/09/17
そえじま@勉強中です。
[#47433] Re: <=>の意味は?
— 藤川浩明 <fhir0aki3@...>
2010/09/18
GyRCISE/JyE5SlZFeiQ3JD8kJCRIO1ckJCReJDckPyQsISI7fjRWJCxMNSQkJE4kRyFWGyhCT09Q
[#47435] Re: <=>の意味は?
— "T.Soejima" <clev@...2.so-net.ne.jp>
2010/09/18
そえじま@勉強中です。
[#47438] Re: <=>の意味は?
— masayoshi takahashi <maki@...>
2010/09/18
高橋征義です。『たのしいRuby』の著者の片割れの方から来ました。
[#47441] Re: <=>の意味は?
— "T.Soejima" <clev@...2.so-net.ne.jp>
2010/09/18
そえじま@勉強中です。
[#47444] Re: <=>の意味は?
— arton <artonx@...>
2010/09/18
artonです。
[#47498] Bignumの変換のタイミングについて — "Jun'ya Shimoda" <jun-shimo@...>
下田と申します。お世話になっております。
5 messages
2010/09/30
[ruby-list:47380] Re: Ruby/Tk Listbox
From:
Hidetoshi NAGAI <nagai@...>
Date:
2010-09-08 11:39:13 UTC
List:
ruby-list #47380
永井@知能.九工大です.
# 現実逃避で長文になってしまいましたが,御容赦を (^_^;
From: Masutoyo Kawamura <m-kwmr@po.hyper-tsukumi.jp>
Subject: [ruby-list:47379] Ruby/Tk Listbox
Date: Wed, 8 Sep 2010 19:10:38 +0900
Message-ID: <20100908191200.44b532df.m-kwmr@po.hyper-tsukumi.jp>
> Ruby/Tk の Listbox に 1秒おきに、1行 表示したいのですが、
> 5秒後に一気に5行表示されます。
まずは前置きですが,イベントループである Tk.mainloop は,
「ボタンが押された」などのイベントに対応した処理のほか,
画面表示の更新も受け持っています.
時間のかかる画面表示の更新を変化がある度に毎回必ず行っていると
イベントに対する反応が遅くなってしまいますから,
即応が必要なイベントが途切れた時 (idle loop) を見計らって
画面表示の更新をまとめて行います.
# もちろん,即応が必要なイベントが届けばそちらが優先されます.
さて,そうした前置きの下に河村さんのサンプルを見ると,
ボタンが押された際のコールバックが 5 秒間終了しないことがわかります.
これは「ボタンが押された」という一つのイベントに対する処理ですから,
イベントループはそれに付きっきりになってしまいます.
そのため,表示に限らず,あらゆるイベントに対して反応できなくなります.
しかしながら,発生したイベントはイベントキューに溜まっていますから,
コールバックが終了した後に溜まっていたイベントが
一気に処理されることになってしまいます.
多分,これは嬉しくない状況でしょうね.
> 意図したようにするには、どうしたら良いのでしょうか。
表示の更新の問題もありますが,
こうした時間がかかるコールバックを有する GUI の設計として,
同時に複数回のボタンクリックを許すのかという問題もあります.
多分,この例の場合にはコールバックが終了するまでは
並行して動いてほしくはないのでしょうね.
順に考えていきましょう.
まずは「表示が更新されない」ということだけを解消したい場合です.
これについては望むタイミングで強制的に表示を更新してやればいいわけです.
この↓ように sleep 1 の前に Tk.update を入れてやると,
------------------------
#!/usr/bin/env ruby
require 'tk'
l = TkListbox.new(:width=>40, :height=>10).pack(:fill=>:both, :expand=>:true)
TkButton.new(
:text => 'Button',
:command => proc{
for i in 1 .. 5
l.insert('end',"This is line #{i}")
Tk.update
sleep 1
end
}
).pack
Tk.mainloop
------------------------
表示更新を含めて溜まっているイベント処理がなくなるまで
その位置でサブイベントループが動くような形となります.
もう一つは Thread を使うやり方です.
この↓ように
------------------------
#!/usr/bin/env ruby
l = TkListbox.new(:width=>40, :height=>10).pack(:fill=>:both, :expand=>:true)
TkButton.new(
:text => 'Button',
:command => proc{
Thread.new{
for i in 1 .. 5
l.insert('end',"This is line #{i}")
sleep 1
end
}
}
).pack
Tk.mainloop
------------------------
時間がかかる処理は別 Thread にしてしまって
コールバック処理自体はさっさと終了させてしまうわけです.
そうすることでイベントループ自体は
時間がかかる処理に煩わされなくなりますから,
表示もスムーズに更新されます.
さて,上記のように修正した場合,
いずれの例でもコールバック処理の実行中に
更なるボタンクリックを受け付けてしまい,
複数回のクリックの表示が混ざってしまうと思います.
これを避ける場合の GUI のデザインとしては
表示が終了するまではボタンの動作を禁止するという方法と,
ボタンの入力だけは受け付けておいて,
終了するごとに順に実行するという方法とがあると思います.
処理としては後者の方がやや面倒です.
前者については,ボタンの state 属性を操作してやればいいので,
例えば
------------------------
#!/usr/bin/env ruby
l = TkListbox.new(:width=>40, :height=>10).pack(:fill=>:both, :expand=>:true)
b = TkButton.new(
:text => 'Button',
:command => proc{
Thread.new{
b.state :disabled
for i in 1 .. 5
l.insert('end',"This is line #{i}")
sleep 1
end
b.state :normal
}
}
).pack
Tk.mainloop
------------------------
のようにすれば (ローカル変数の使い方があまり良くないかもしれませんが)
コールバック (を実行中のスレッド) の動作中はボタン操作が禁止されます.
もう少し丁寧に,コールバック処理中に異常が発生しても
ボタンの状態をきちんと戻したいなら,
------------------------
#!/usr/bin/env ruby
l = TkListbox.new(:width=>40, :height=>10).pack(:fill=>:both, :expand=>:true)
b = TkButton.new(
:text => 'Button',
:command => proc{
Thread.new{
b.state :disabled
begin
for i in 1 .. 5
l.insert('end',"This is line #{i}")
sleep 1
end
ensure
b.state :normal
end
}
}
).pack
Tk.mainloop
------------------------
くらいのことをしておいた方がいいかもしれませんね.
最後に,コールバック中もボタン操作を受け付ける
(ただし,実行は順次) としたい場合です.
考えれば色々な方法がありそうですが,
一例として,ここではコールバックを順次処理するための queue を
使った例を示して終わりにします.
------------------------
#!/usr/bin/env ruby
l = TkListbox.new(:width=>40, :height=>10).pack(:fill=>:both, :expand=>:true)
callback_queue = Queue.new
Thread.new{
loop{
begin
cb = callback_queue.pop
cb.call
rescue Exception
end
}
}
b = TkButton.new(
:text => 'Button',
:command => proc{
callback_queue.push proc{
for i in 1 .. 5
l.insert('end',"This is line #{i}")
sleep 1
end
}
}
).pack
Tk.mainloop
------------------------
--
永井 秀利 (nagai@ai.kyutech.ac.jp)
九州工業大学大学院情報工学研究院知能情報工学研究系知能情報メディア部門助教