2012-02-04 51 views
0

以下代碼創建3個按鈕並向每個按鈕添加處理程序。退出按鈕工作,放棄按鈕產生一個錯誤NameError未知選項settings_change,並建議一個對象已被刪除。與「下一步」按鈕相同。當我把事件處理程序放在類之外時,代碼工作正常。Ruby/TK按鈕事件處理程序代碼未按預期觸發

事實證明,如果通過先執行next_note_proc = proc {next_note}之類的操作來創建回調,那麼在按鈕創建命令next_note_proc中。爲什麼這個工作?

爲什麼在課堂內外,回調的工作方式不同?從全球範圍內運行按鈕執行

require 'tk' 
require 'tkextlib/tile' 

class App 

    def next_note 
    puts "Got next note" 
    end 

    def settings_change 
    puts "Got settings change" 
    end 

    def quit 
    puts "Got exit" 
    exit(1) 
    end 

    def initialize 
    $number_correct = TkVariable.new; 
    $mode = TkVariable.new 

    @root = TkRoot.new {title "Music Training"} 
    @content = Tk::Tile::Frame.new(@root) {padding "0 0 0 0"}.grid(:sticky => 'nsew') 

    @a = Tk::Tile::Button.new(@content) {text 'Next'; command {next_note}}.grid(:column => 1, :row => 1, :sticky => 'w') 
    @b = Tk::Tile::Button.new(@content) {text 'Give up'; command {settings_change}}.grid(:column => 2, :row => 1, :sticky => 'w') 
    @c = Tk::Tile::Button.new(@content) {text 'Quit'; command {quit}}.grid(:column => 2, :row => 2, :sticky => 'w') 
    TkWinfo.children(@content).each {|w| TkGrid.configure w, :padx => 0, :pady => 0} 

    @c.bind("1") {quit} 
    @a.bind("1") {next_note} 
    @b.bind("1") {settings_change} 

    puts "Starting up" 
    end 

    def run 
    Tk.mainloop 
    end 

end 

the_app = App.new 
the_app.run 
+0

經過反思,這是相同的問題http://stackoverflow.com/questions/1723101/ruby-tk-command-binding-scope-issue – qpit3a 2012-02-04 21:44:38

+0

只是不明白到底是怎麼回事。 – qpit3a 2012-02-04 21:45:30

回答

0

命令,但settings_changequitnext_note是在類的上下文。當您使用proc命令時,它會創建一個新的對象,該對象調用該方法,並可以從其他上下文中調用該對象。

的原因quit命令似乎工作,可能是因爲有一個在全球範圍內,這是獲得所謂的另一quit命令 - 它幾乎肯定不會調用App對象的quit方法。您可以通過在quit方法中添加打印語句來驗證。

相關問題