Следующий код создает 3 кнопки и добавляет обработчик к каждой. Кнопка Quit работает, кнопка Give Up выдает ошибку NameError неизвестной опции settings_change и предполагает, что объект был удален. То же самое с кнопкой «Далее». Код работает нормально, когда я помещаю обработчики событий за пределы класса.
Оказывается, что если обратный вызов создается, сначала сделав что-то вроде 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