速度、コーディングのしやすさともに、wxRubyがかなり気に入りつつある。ただ、早くもいくつかの不具合に当たったり、少しハマったところがあったので、まとめておく。
raiseするとwrong # of arguments(1 for 0) (ArgumentError)
仕様ミスでWx::Window#raiseメソッドとコンフリクトしている(wxRuby 2.0.0現在)。解決策としてはriseの代わりにKernel.raiseを使えば良い。この問題はwxRubyの不具合として認知されており、すでにWx::Window#raiseはdeprecatedとなっていて、Wx::Window#bring_to_frontを使うことが推奨されている。
Wx::ListCtrl#get_selectionsで常に[]が返る
バグっているようなので(wxRuby 2.0.0現在)、暫定的に次のようにメソッドを再実装して解決。
class Wx::ListCtrl
def get_selections
selections = []
item = get_next_item(-1, Wx::LIST_NEXT_ALL, Wx::LIST_STATE_SELECTED)
while item >= 0
selections << item
item = get_next_item(item, Wx::LIST_NEXT_BELOW, Wx::LIST_STATE_SELECTED)
break if item == 0
end
selections
end
end
参照:http://www.ruby-forum.com/topic/181089
(このコードも不具合があったので上記コードで修正済み)
スレッドが回らない
仕様?
Timerを設定して定期的にThread.passを呼んでやる必要がある。 Wx::Window#initializeで次のようにしておく。
Wx::Timer.every(10) { Thread.pass }
ウインドウに制御を渡す方法
でも上記のようにして動かしたスレッドは遅いので積極的に使いたくはない。しかし時間のかかる処理を普通に行うとウインドウが固まってしまうので、定期的にウインドウに制御を渡す必要がある。そのためにはループ内などで定期的に次のようにする。
Wx::get_app.yield
ノンプリエンプティブマルチタスクなOSではもちろん必須。今どきそんなOSがあるのかどうかは知らないが。
追記)・・・・上記は間違い。溜まったイベントを処理しないとウインドウに制御が渡らなくなることがあるみたいだ。こちらが正しいみたい。
Wx::get_app.dispatch while Wx::get_app.pending