Как запретить команду кнопки, если нажатие кнопки также устанавливает фокус?

#tcl #tk

#tcl #tk-toolkit

Вопрос:

В моем приложении есть команда, привязанная к кнопкам мыши. Я пришел к выводу, что раздражает, когда вы нажимаете на окно, чтобы установить фокус, и оно также выполняет команду кнопки.

Вот строка, привязывающая мою команду к кнопке 1:

 bind .f.canvas <Button-1> {panto %W %x %y 0.5}; # pan half distance
  

Как запретить вызов команды кнопки, когда нажатие кнопки также используется для установки фокуса?


Вот моя «тестовая последовательность»:

  1. Откройте программу
  2. Нажмите на холст. Желаемый / результат: панорамирование в выбранное положение.
  3. Нажмите на рабочий стол.
  4. Нажмите на холст. Желаемое: Нет панорамирования. Результат: панорамирование в выбранное положение.
  5. Нажмите на холст. Желаемый / результат: панорамирование в выбранное положение.

Ответ №1:

Мое текущее решение — это небольшой взлом. Я переключаюсь на событие фокусировки клавиатуры в виджете ввода, временно отключая команду button, пока ввод не находится в фокусе:

 ttk::entry .f.cmd -textvar e -width 30
bind .f.cmd <FocusOut> {
  puts "focus out, disable button press"; 
  bind .f.canvas <Button-1> {}
}
bind .f.cmd <FocusIn> {
  puts "focus in, enable button press starting next event"; 
  after idle {
    bind .f.canvas <Button-1> {
      panto %%W %%x %%y 0.5
    }
  };
}
  

Протестировано на Win10, Tcl 8.6.

Комментарии:

1. Я думаю, вы могли бы просто проверить в своей panto процедуре, какой виджет имеет фокус, и ничего не делать, если это не холст…

2. Проблема @DonalFellows в том, что событие FocusIn обрабатывается перед Button-1, поэтому оно всегда будет true. Для этого after idle и предназначен.

Ответ №2:

Если вы завершите свой сценарий привязки с помощью break , он не будет запускать ни один из других сценариев, связанных с этим событием (например, на уровне класса виджета, всего уровня окна или на уровне всего приложения). Конкретно, вы делаете это:

 bind .f.canvas <Button-1> {
    panto %W %x %y 0.5; # pan half distance
    break
}
  

Такого рода вещи — один из немногих случаев, когда рекомендуются сценарии привязки с несколькими командами. Обычно лучше (для понятности) извлекать данные в процедуру, но в этом случае лучше ввести break напрямую.

Комментарии:

1. Это не делает то, что я хочу. Есть решение для взлома, опубликую это и лучшее описание.