Код обработчика события кнопки Ruby / TK работает не так, как ожидалось - PullRequest
0 голосов
/ 04 февраля 2012

Следующий код создает 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

1 Ответ

0 голосов
/ 25 февраля 2012

Команды, выполняемые из кнопок, запускаются в глобальном контексте, но settings_change, quit и next_note находятся в контексте класса.Когда вы используете команду proc, она создает новый объект Proc, который вызывает метод и может вызываться из других контекстов.

Причина, по которой команда quit кажется работать, вероятно, потому, что в глобальной области видимости вызывается другая команда quit - она ​​почти наверняка не вызывает метод quit объекта App.Вы можете убедиться в этом, добавив оператор print в методе quit.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...