新井です。

# 調子にのってまたパッチ付けます。関連パッチを集めるという意
# 味でこのままこのスレッドに続けます。

現状の、Ruby/Tkではウィジェットクラスに対してイベントコール
バック関数を登録できません。

で、以下を提案します。

・モジュールTkに以下のモジュールメソッドを追加
  (他のメソッドにならって実際にはインスタンスメソッドで定義してます)

  o Tk.bind
  o Tk.bind_append
  o Tk.bindinfo_all (Tk.bindinfo "all" と同じ。ついで)

  e.g.)
     require "tk"

     Tk.bind TkButton, "1", proc {p "button 1 pressed (class binding)"}
     p Tk.bindinfo TkButton, "1"

     b1 = TkButton.new.pack
     Tk.bind b1, "1", proc {p "button 1 pressed"}
     p Tk.bindinfo b1, "1"
     Tk.mainloop

     => [[#<Proc:0x40134b88>, "%# ... "]]
        [[#<Proc:0x401320f4>, "%# ... "]]

  e.g.)
     require "tk"
     p Tk.bindinfo_all
     p Tk.bindinfo_all "Tab"

     => ["Shift-Key-Tab", "Key-Tab", "Key-F10", "Alt-Key"]
        ["tkTabToWindow [tk_focusNext %W]"]

・モジュールTkBindを追加
  o TkBind#bind
  o TkBind#bind_append
  o TkBind#bindinfo

・TkBindをTkObjectでinclude、TkWindowで extend
  (include、extendするクラスの選別はあまり考えず元の定義に倣
  いました。TkWindowのオブジェクト以外でTkBindが必要なのかど
  うか考えてないので。もしかしたら、モジュールにする意味がな
  いかも知れない)

  o TkObject#bind
  o TkObject#bind_append
  o TkObject#bindinfo

  o TkWindow.bind
  o TkWindow.bind_append
  o TkWindow.bindinfo

  e.g.)
     require "tk"

     TkButton.bind "1", proc {p "button 1 pressed (class binding)"}
     p TkButton.bindinfo "1"

     b1 = TkButton.new.pack
     b1.bind "1", proc {p "button 1 pressed"}
     p b1.bindinfo "1"
     Tk.mainloop

     => [[#<Proc:0x40134ca0>, "%# ... "]]
        [[#<Proc:0x401322d4>, "%# ... "]]

・以下のようにしたとき、bindtagsがエラーになるので修正しました。

  ruby -rtk -e 'b = TkButton.new' -e 'b.bindtags [Tk.root]' -e 'p b.bindtags'
  => -e:3: undefined local variable or method `collect' \
     for #<TkRoot:0x40134858> (NameError)

・bindtags の以下の部分は必要ないように思えましたので削除しました。
  (自信はない)

tk_split_list(tk_call('bindtags', path)).collect{|tag|
  if tag == nil        <- ココ
    "."                <- ココ
  elsif ....
}


--- ext/tk/lib/tk.rb.old Tue Dec 21 23:03:34 1999 +++ ext/tk/lib/tk.rb Thu Dec 23 22:58:21 1999 @@ -349,6 +349,14 @@ module TkComm end private :install_bind, :tk_event_sequence, :_bind_core, :_bind, :_bind_append + def bind(tagOrClass, context, cmd=Proc.new, args=nil) + _bind(['bind', tagOrClass], context, cmd, args) + end + + def bind_append(tagOrClass, context, cmd=Proc.new, args=nil) + _bind_append(['bind', tagOrClass], context, cmd, args) + end + def bind_all(context, cmd=Proc.new, args=nil) _bind(['bind', 'all'], context, cmd, args) end @@ -372,11 +380,16 @@ module TkComm } end end + private :_bindinfo def bindinfo(tagOrClass, context=nil) _bindinfo(['bind', tagOrClass], context) end + def bindinfo_all(context=nil) + _bindinfo(['bind', 'all'], context) + end + def pack(*args) TkPack.configure *args end @@ -1573,9 +1586,24 @@ module TkTreatFont end end +module TkBind + def bind(context, cmd=Proc.new, args=nil) + Tk.bind(to_eval, context, cmd, args) + end + + def bind_append(context, cmd=Proc.new, args=nil) + Tk.bind_append(to_eval, context, cmd, args) + end + + def bindinfo(context=nil) + Tk.bindinfo(to_eval, context) + end +end + class TkObject<TkKernel include Tk include TkTreatFont + include TkBind def path return @path @@ -1672,18 +1700,6 @@ class TkObject<TkKernel end end - def bind(context, cmd=Proc.new, args=nil) - _bind(["bind", to_eval], context, cmd, args) - end - - def bind_append(context, cmd=Proc.new, args=nil) - _bind_append(["bind", to_eval], context, cmd, args) - end - - def bindinfo(context=nil) - _bindinfo(['bind', to_eval], context) - end - def event_generate(context, keys=nil) if keys tk_call('event', 'generate', path, @@ -1707,7 +1723,7 @@ class TkObject<TkKernel end class TkWindow<TkObject -# extend TkClassBind + extend TkBind def initialize(parent=nil, keys=nil) install_win(if parent then parent.path end) @@ -1855,10 +1871,8 @@ class TkWindow<TkObject fail unless taglist.kind_of? Array tk_call('bindtags', path, taglist) else - tk_split_list(tk_call('bindtags', path)).collect{|tag| - if tag == nil - '.' - elsif tag.kind_of?(String) && (cls = WidgetClassNames[tag]) + list(tk_call('bindtags', path)).collect{|tag| + if tag.kind_of?(String) && (cls = WidgetClassNames[tag]) cls else tag -- 新井康司 (Koji Arai)