From: matz@... (Yukihiro Matsumoto) Date: 1997-12-09T14:14:18+09:00 Subject: [ruby-list:5610] How to make Composite Widget (Re: megawidgets) まつもと ゆきひろです In message "[ruby-list:5609] Re: megawidgets" on 97/12/09, Kikutani Makoto writes: |きくたにです。 |> # 乗る人がいれば,TkCompositeの使い方を説明しますけど. | |お願いします。ぼちぼちでよろしければやってみたいと思います。 了解です.このメールは保存版ですね(長いです). = Composite Widgetの作り方 == Composite Widgetとは 複数のウィンドウ部品がまとまってできているウィンドウ部品のこ とです.Ruby/TkではTkCompositeモジュールを使うことによって比 較的簡単にComposite Widgetを作ることができます. # Ruby/TkのComposite Widgetの作り方はSTkのSTklosが元になって # います. == 作り方 実例を見ながら作ってみましょう.Composite Widgetの実例として TkScrollBoxを見てみます.これはScrollbarが付随したListboxに なります.プログラムは以下の通りです. 1 # 2 # tkscrollbox.rb - Tk Listbox with Scrollbar 3 # as an example of Composite Widget 4 # $Date: 1995/12/12 18:21:01 $ 5 # by Yukihiro Matsumoto 6 7 require 'tk.rb' 8 9 class TkScrollbox'left','fill'=>'both','expand'=>'yes' 18 scroll.configure 'command', list.path+" yview" 19 scroll.pack 'side'=>'right','fill'=>'y' 20 21 delegate('DEFAULT', list) 22 delegate('foreground', list) 23 delegate('background', list, scroll) 24 delegate('borderwidth', @frame) 25 delegate('relief', @frame) 26 end 27 end まず,tkモジュールをrequireして,それからクラスTkScrollbarを 定義しています(7,9行目). TkScrollbarはTkListboxのサブクラスとして定義していますが,こ れはTkScrollbarがTkListboxの振舞い(特にメソッド)を引き継ぎた いからです.特にそのようなクラスが存在しない場合,TkWindowの サブクラスにします.Tkクラスの構造の違いについて考える必要は ありません(実は全てのTkクラスは同じ構造を持っています). それから,TkCompositeモジュールをincludeします.これは Compsite Widgetを定義する際に必須です. 次にinitialize_compositeメソッドを定義します.これは通常のク ラスにおけるinitializeに相当する初期化メソッドです.なお, Composite Widgetのクラスはinitializeを再定義してはいけません. このinitialize_compositeメソッドではCompositeの内部部品を生 成し,配置します.このメソッドの中では,内部部品を囲むフレー ムとしてインスタンス変数 @frame にTkFrameオブジェクトが与え られていますから,それを使って生成と配置を行います(12〜19行 目まで). 14行目ではインスタンス変数 @path にlistのパスを設定していま す.これは継承したTkListboxのメソッドを動作させるために必要 です.TkWindowクラス以外のクラスから継承したComposite Widget を定義する場合にはこのようにして @path にそのクラスのオブジェ クトのpathを代入しておく必要があります. さて,次に「属性の委譲」を行います(21〜25行目).これは configureなどで設定される属性をどのオブジェクトに投げるかを 設定します.例ではforegroundなどはlistに,borderwidthや reliefは@frameに,backgroundはlistとscrollに,残りの属性 (DEFAULTで指定)はlistに委譲しています. これでinitialize_compositeの定義は終りです.newへの引数は(親 を指定した第1引数以外は)initialize_compositeにも引き渡されま すから,ここでconfigureを呼んでおいた方が良いかも知れません. その場合は def initialize_composite(keys=nil) ... tk_send 'configure' *hash_kv(keys) if keys end となるでしょう. さて,例はここで終りですが,必要によってはそのクラスに特有の メソッドを定義する必要があるでしょう.後で参照する必要のある 内部部品はインスタンス変数に代入してとっておきましょう.メソッ ドの書き方はtk.rbの他のメソッドを参照して下さい.@path(基本 的なメソッドを引き受けるTkの実体)と@epath(外側を囲むTkの実体) に気をつければそんなに難しくないはずです. まつもと ゆきひろ /:|)